本帖最后由 hello怪 于 2017-7-25 22:24 编辑
3 u3 d) ~9 F; E$ _+ x6 ?
( m/ ^/ ?+ Q p% T+ |(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
- @) B: _2 n9 m8 }/ U8 ^
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
# G+ s1 g% u O+ f) } v* |场地
3 l, b# [# g) J! B6 p( J 水平度和光滑度
在家里当然瓷砖的效果是最好的
! G8 d5 i R6 X [. m 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直/ k* v7 s1 ^/ P" G& A5 ?# [. v& V
$ _; J' A0 c, H' N1 Y, L
车子结构: p2 y& H0 r# g- b9 h: `. s
轮子间距; x3 ^4 ]" }; |7 L3 _ g
轮子间距越大越好,稍微想一下便知
! b) l% r- w4 ~4 `- b 轮子大小" [3 Q; c1 J6 G, a: g
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
& Y" _$ H8 x8 S( Q7 O) X 随动轮的设计
* V* M9 k) d) X 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
/ A& t/ G$ i, R. @# b& `4 Q6 E( i; { 重心位置9 N+ ~1 g2 }7 ]' C5 W2 f4 Z# n6 E
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小 T" }3 w1 m( A7 o
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大) _& a8 V+ X5 \0 V
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
_ Q; T, P# g" N# b& N 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
- A& M) B' x0 i; o- J7 U
2 b9 E4 r1 ]- U控制程序$ n' _( m4 {( K% q
运动过程控制5 K4 X' \$ j4 k) F6 @
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
9 j+ p* F% C* i! ?* q( B; N$ G; N, |( P4 F9 t% d# |% }/ F
调试与运行+ w/ V6 u: c% K" n' K: j
轮子转速调整(车轮大小的设定)
, R( f) R! H- Y" y 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法; S: V) w5 n' W! k' h9 ^
起始位置车子正方向和直线间的夹角& ]+ S7 }6 U9 O' \, z8 z
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 + n0 F2 s9 {. q
4 |# v# v5 U9 f6 x5 Q. Y! v& l: D) y' U/ k1 {1 I2 H$ N! O, X# h* b3 r
然后上源代码:
7 K+ a1 X/ g7 B/ I, \- importlejos.robotics.navigation.DifferentialPilot;7 o, F, w3 B5 \7 y
- import lejos.util.Delay;
* e& n) l+ ?- F% D1 O- _. w. l: z8 M - " k: h% T( b; f+ I& n5 V2 h4 U
- /**
5 S1 k& @+ S) Q8 d - *Robot that stops if the buttons are presses before it completes its travel.
- U. z4 r" q3 K6 f8 o# m9 c - */
' {' ^6 l2 `* z0 X
+ u& |6 k% n S2 e s- # B K1 p* V, A* O% x3 G( ]' w
- public class Straight {* ?/ K* v8 l5 r
- DifferentialPilotpilot;; u A7 S- D+ ^0 [/ M9 v( }( U( }
- doubleleftD = 4.3, rightD = 4.3;
5 G3 @+ Q7 V# X0 m: N8 ^" I/ \ - o- N) r) y# k9 O4 }7 E
- publicvoid adjust() {
# h3 D' h2 u/ {+ N, v2 M - //wait for release
% ?5 x+ _7 z3 R! g- H4 x3 K - while(Button.readButtons() > 0)
7 ]6 Z y: `& Y0 a - ;
0 v3 S Y0 h% f( l# x7 t! p - while(Button.readButtons() == 0) {
8 W2 M, ^) S! e4 V: C - //input size by adjusting the wheels
, D) l/ M6 @7 K, M |5 Y Z9 r - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
1 m( m0 U H" H/ K - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值& P b: Y, W4 T U) L- A! J
6 f1 z* y2 z/ V' R t" _0 l* C! l) `- //display the size input
; e. D8 {# h! j; w; V - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
0 h6 f( ^# ?- F7 w( w - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
2 f, }" x5 Z* _1 j9 n+ s - Delay.msDelay(100);3 |' y$ R3 H7 A7 ` O1 o& u Z
- LCD.clear();
\) @ q4 j0 S1 K7 z+ e - }
! D0 r: Z1 U' y" r$ |
% I* ^( r8 a0 |1 q, w- }4 h; _" A% o- r7 k B* v& O p* i5 f
# S9 ~& p! ~ B. Z5 }$ F) B- publicvoid go() {
; C/ b% W u, u - //准备起步
" `, V% g4 z! O. c' R2 c. V8 N - //wait for release
& J; d% E' h: g7 k; @+ _ - while(Button.readButtons() > 0)
, a& x+ ~) N; Y4 b$ u' K5 d/ V- z& j - ;
5 Q8 J1 G$ x* p( ?1 o5 j, | - System.out.println("pressto go");
9 f" g- g; d' L1 Z. d# p# b - + ^, I' _7 g+ h) k5 ~
- Button.waitForAnyPress();
9 o; x7 j" v3 d - LCD.clear();: T% w4 Z) w- S
1 q8 i3 H9 y7 A% n ^' ?- //初始化7 p7 _% E$ Z# s' ]
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
) L/ f. v; z) t* r" f - pilot.reset();
. p; S k1 K' v( j V) G2 B - % [+ K/ }' x2 H; H! y% Y5 C- g
- Delay.msDelay(3000);
' ~& A) O9 i/ o3 U1 {
: X7 P0 d0 @, S, G: ^3 o! O1 F- doublespeed = 10;! ]. N# c: c- b
- doubledistance = 0;0 }. L7 a) }! ?: F+ @
% e G9 z8 r" I' C- //起步加速8 i! S7 G. r4 I0 l- _; _% W4 \
- pilot.travel(300,true);2 N/ J' ~& C# T1 Q
' q* E+ w) Q! _' |* B- while(distance < 20) {
! S7 C( a( Q' l - distance= pilot.getMovement().getDistanceTraveled();. h2 a$ D2 G8 \4 @9 L/ ] q
- speed= distance * 5 + 10;5 X F7 b* Q# K4 D2 Z
- pilot.setRotateSpeed(speed);
% o( N# J s: ]$ w7 N" _7 x6 ] - Delay.msDelay(100);$ O/ p4 ]7 h3 s/ w+ Q- K2 ~/ y+ O+ P
- }
4 ^$ O4 D0 E" _ - for(int i = 0; i < 10; i++) {$ V M# T: O5 K0 J- x, k
- speed+= 5;
8 t$ b7 J: F, C" B - pilot.setRotateSpeed(speed);
* Y6 T/ p# p: H1 }2 H - Delay.msDelay(200);* V9 ^+ O3 j% J+ U0 P6 a
- }4 A* q+ O: z5 V* u3 u
" D% l; @9 ?4 {! Q& c- //TODO 减速
) y7 {7 i# s2 D! u- p - ; ? G# C. J0 m# I3 ^8 Y2 W$ `
- //停止机能
4 v6 q& S: _; n) R* |7 w - while(pilot.isMoving()) {* j0 y1 }2 A) h! r$ u9 g, N% r
- if(Button.readButtons() > 0)) E2 Q2 x" F L5 {
- pilot.stop();+ a# m" m% C8 ?! y8 W9 G
- }% V' R: K. q3 H8 @* n- c
% i/ w/ ]6 y, p1 H3 S0 n$ V6 F- System.out.println("" + pilot.getMovement().getDistanceTraveled());
' Y5 s* P$ x+ ~1 Y - System.out.println(-Motor.A.getTachoCount());3 E4 L$ W( y& u( f: \
- System.out.println(-Motor.B.getTachoCount());) y( N: `% T( m# }9 @
- Button.waitForAnyPress();( U& v( j7 u( ~2 x8 Y
- }9 @" Z% X+ g, G, l# `% q. c
- 9 ?% o1 J! A; Q0 P0 K" c
- publicstatic void main(String[] args) {
- \( M; p* Y8 S& _% Y! D - Straighttraveler = new Straight();
: j+ j$ y1 |* S! t, H; L* |% ~% X
; u( u m* |9 M5 R7 U2 u& B) j5 p8 D- traveler.adjust();
1 G8 f, |% @6 P$ E3 X+ T - traveler.go();6 L2 k1 m, n% K! C. H/ k
- }3 v, @# v3 `! _8 i; P$ [
- }
复制代码
. O3 s% L3 ^# ^4 H0 n& H |