本帖最后由 hello怪 于 2017-7-25 22:24 编辑 # U9 _: X5 M/ d' Z# z3 `
$ ^ i; T$ b0 q
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html 4 q/ r1 y. r' x" |. J9 l
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
: c6 _& H1 } g- J/ t) j场地3 J; L( p- B- V1 @! L0 v* _, R
水平度和光滑度
在家里当然瓷砖的效果是最好的
( @( @ @. B3 W' \& c+ W4 H( L) F 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直! Y; |' g y" y# ?. l
$ v: f: c+ N4 U. a: d8 I' v车子结构
* r& l8 X6 C5 @4 ] 轮子间距& ]7 z8 s( M: a4 w/ X3 E
轮子间距越大越好,稍微想一下便知
/ Z8 x, _' Z- A$ h: b# f: q 轮子大小
! H0 w0 F r, I4 n( l 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
3 U0 k+ ~- D& W4 ^0 ~8 X+ a 随动轮的设计 B# H4 ~" Y- \2 p& W
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响$ z" H/ J) R- U0 ? k
重心位置
* U' W1 X9 f/ R- f6 y! g2 { 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
, O- d) X* u/ `& l; a+ g, X, h 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
' G6 T- L% i2 l" |% {7 I7 w) S 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
! _/ v; s$ c$ O% ^ 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
& z* }9 m( p% ~ m$ W, G. i) v) V
5 p" o5 O# `! W; p J控制程序* g( c p* r/ Q, L9 g
运动过程控制
4 i3 {. D2 ]3 ^! v 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
( W$ h' G! N! e W
6 w7 }" D7 J" n) A调试与运行
7 J$ E* w# |: _, Y1 [ 轮子转速调整(车轮大小的设定)7 O! D/ u2 N5 j. H4 K- ?4 W, G
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法1 m9 I$ }8 `4 {& k% n
起始位置车子正方向和直线间的夹角
0 Y$ E: u* ], {$ H 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
/ w8 Y3 K: Z. U6 F& x
5 Z. l) E3 [( Y" F6 `2 D3 I
. W* v/ ^' k3 y 然后上源代码: - + p) q; @7 y0 Q6 o
- importlejos.robotics.navigation.DifferentialPilot;
0 o, D/ J+ {, _ - import lejos.util.Delay;
3 f! B4 {/ d) u3 Z7 b/ } - 8 p+ J( D3 j5 ^# q4 G7 ~
- /**
6 Y e: i* r; `- u( r - *Robot that stops if the buttons are presses before it completes its travel.5 m. _; o+ Y; K/ {% ]
- */
. T" \7 \+ D7 S$ i/ S/ G- w
3 g) B$ J1 n& K" ]8 v
2 u8 V6 ]% V/ P/ \5 o) _" q( L3 m- public class Straight {
( q/ E) K4 T1 h - DifferentialPilotpilot;
) D1 {2 M2 w# ?* I: ?2 A8 }& l - doubleleftD = 4.3, rightD = 4.3;3 `8 ?3 D) m& L9 G) P, J
! d0 Z; S2 `/ `$ ]3 n- publicvoid adjust() {" e8 W% u3 K+ k
- //wait for release
2 f1 L" M0 x4 {) a& V - while(Button.readButtons() > 0); | h0 c! v- A& [" F/ w
- ;8 c: s/ p5 A. x# N* ~3 |
- while(Button.readButtons() == 0) {
]1 W0 l1 Q1 v' H8 w: f& f* y p - //input size by adjusting the wheels
1 b6 |# |# p3 O/ P4 W# B7 T - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
/ J. p9 T( R. C& S7 C% X" \ - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
; [# N6 G9 E6 p' G
+ X5 E$ E* _* z- //display the size input) I! K2 o0 | M$ Q) h& M8 Z$ h
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);5 _6 v2 |" _; `
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
: Z1 p. ~ H( |2 E3 ]' y - Delay.msDelay(100);: Y7 |; b: g+ _
- LCD.clear();4 e9 @" }" _1 [5 j
- }3 s- F9 }- p) \- N
- j( W; a( y5 `# ^! g4 S* S
- }
4 Q4 z/ o1 ]8 W z% G& c. J# A
( X- U7 E) D9 R5 n6 Z- publicvoid go() {
. c. U( ]5 _' p# n9 ?0 `& n - //准备起步& J, G* L+ a& Y" U
- //wait for release
$ _8 S5 G8 |7 v. |" s7 N: m - while(Button.readButtons() > 0); I; w9 {. d% v5 A# g8 w
- ;* E b9 U& f8 x$ Q6 @: f( s
- System.out.println("pressto go");! Z: D: S O% h
- ; l2 p; l+ d! D" `
- Button.waitForAnyPress();
6 k, F1 Y0 N+ h' I( U - LCD.clear();' u' P5 ~1 @' X' q) b) j
e7 T/ @3 d/ e- //初始化
$ Y" v+ r' H! L+ X - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);' _2 M1 m' @/ I# U" i4 v
- pilot.reset();% [( R9 T" G% W9 S
# i" r" L' W6 l- Delay.msDelay(3000);
) a" x- A& m9 u
8 S+ T6 |# A$ b! x% {; `: A; D- doublespeed = 10;' H0 l5 B P# a" B
- doubledistance = 0;2 G4 X4 f7 Q l0 Q' |" }
: }$ q J* x' s8 o- //起步加速& {* M' r: x( Z7 F) r
- pilot.travel(300,true);
6 M1 O. H4 {% u p - 8 d2 ?% u( d1 U; G, T! a' } X
- while(distance < 20) {) ?8 b) V6 [0 P+ N7 R" a2 M3 J
- distance= pilot.getMovement().getDistanceTraveled();
+ @& s3 r$ Q+ N - speed= distance * 5 + 10;
# h1 {& D7 W$ O2 R; C - pilot.setRotateSpeed(speed);
+ ?* k! B5 u# p - Delay.msDelay(100);4 u3 w0 T; r( n5 x( M
- }( Y% Y _1 E# x2 z
- for(int i = 0; i < 10; i++) {
. ~: ^ E8 q2 `9 }: c' E: Y- _ - speed+= 5;
* N P9 ^0 r1 z% u7 t- H - pilot.setRotateSpeed(speed);5 [9 p; h- s/ M7 D) P
- Delay.msDelay(200);
3 `3 W( R" j t/ t; u, x - }, W9 w1 u5 s9 U% c9 R" T
- 9 m, m) J3 M( \1 B& V0 U) G$ g; }
- //TODO 减速, ^5 z3 _! a# D
0 x( J6 d1 y. p+ ~8 G: u- //停止机能5 Q) _. O" N$ t" H
- while(pilot.isMoving()) {7 Z w& \; H" Q: O% H
- if(Button.readButtons() > 0)
+ F2 S$ k) N8 ]6 ` Z - pilot.stop();) g( m* y2 X. N/ L
- }
! L: q. y+ q% T) h
) P0 X( W& d8 a1 r- System.out.println("" + pilot.getMovement().getDistanceTraveled());
9 \# n2 }, d+ m% P1 K - System.out.println(-Motor.A.getTachoCount());& H7 C" |+ o! O3 G* _% t
- System.out.println(-Motor.B.getTachoCount());
$ S" H0 x! L; j0 U* f - Button.waitForAnyPress();& ~% }2 j( A3 D, B
- }$ N" Y- G. B! @- C: n9 G9 S+ I
- 2 l `7 m1 x! v% o1 z1 U2 C
- publicstatic void main(String[] args) {; o, N: W1 h( M) D f. w
- Straighttraveler = new Straight();3 X+ _# T) N; v) Y
- 5 ~: b8 C( _- A
- traveler.adjust();
9 e3 i! l0 Z' B- ~# x1 S - traveler.go(); k3 g' g9 O& M: {; K0 s
- }
+ ~- T1 x0 y6 E - }
复制代码 9 @+ A* J( ~7 K5 U9 o
|