本帖最后由 hello怪 于 2017-7-25 22:24 编辑
. Y, P( Z2 r6 A: g* r* L
+ S* G3 @: A% h(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
0 c1 g, u. T3 v$ g% f
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: ' a6 A H+ l' V Z \
场地' Z* M3 F/ \- H% X& y1 n6 `
水平度和光滑度 在家里当然瓷砖的效果是最好的! w% I: A9 M3 `/ F* r
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直- l f( t* j4 m( c
9 N4 G$ W D4 E7 J
车子结构
5 h' A1 X3 T. M# z5 ]* K6 x 轮子间距! L3 @' E, A0 s C) p
轮子间距越大越好,稍微想一下便知
@ B" d3 L6 ~7 ~ U; C 轮子大小
' Y" ^) }* n( h* U 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)' w7 X" g( D. Y5 I
随动轮的设计
! T( C5 R) w! }4 ?0 w, c; T 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
$ w- r4 L) D4 B1 h; S% ^ 重心位置' B9 o6 W4 j+ j
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小! ]* F; Q* c# k9 X
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大4 E6 N' {! o8 Y# V( A& L! C
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)- ^9 x u5 X5 k% k% c! O
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动7 q; {+ I* m4 K% {( X
+ R; o) R- s$ W5 F0 ~2 t控制程序
0 n& Q5 ~) M, U7 M. G+ Y7 O 运动过程控制
% @2 Z* ?% e2 U: C/ m" @9 \ 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零) O& L, u3 d+ j7 m
% X) a3 x9 i: u5 |调试与运行/ l9 { |+ o" F$ R a/ \
轮子转速调整(车轮大小的设定)* y7 m. j8 n% D
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
( M d7 }' s+ m! R1 K5 e1 v, p 起始位置车子正方向和直线间的夹角
3 d4 O2 z b) L 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
4 @3 a# {% `4 t+ F$ B6 { c. Z
+ R& u4 K/ R: `4 ]6 ]3 g& [
9 V' l2 e" Y* Z: K2 @/ H( |/ k 然后上源代码:
W+ Y6 a5 i+ s5 g/ D# O- importlejos.robotics.navigation.DifferentialPilot;
9 G( V# Z9 n; ` - import lejos.util.Delay;& [6 U. w v2 I0 V) V
) E& Z5 p) C7 x/ h/ t2 c' ]# K } x- /**
! ~1 N" W$ ]2 {( d. p - *Robot that stops if the buttons are presses before it completes its travel.- P4 A( _ w& x
- */. [- L! _0 Q* e
; M) A3 \4 u" M
: i9 i2 i5 D1 Y! o4 B! u- public class Straight {
# m0 `' Y9 _5 k3 r+ ]2 N* g - DifferentialPilotpilot;
$ D" l( ]2 B' P - doubleleftD = 4.3, rightD = 4.3;
& S6 a4 N8 M& ]( m
6 l& `7 I. ], W( {4 o; `/ e- publicvoid adjust() {
# J2 X+ {* J" T - //wait for release
`0 T. g# \1 I7 P - while(Button.readButtons() > 0)
5 T* s/ F( o2 p* E% k+ n( c4 O% z+ E - ;2 \2 `' R3 a1 }5 {1 ~1 K/ r$ f
- while(Button.readButtons() == 0) {; ]! q! O& ]5 G/ |- W
- //input size by adjusting the wheels/ m* i' Z/ N7 {( c
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;5 f2 D3 u% O) j7 r$ h c: E
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值" g5 d+ _. Z% t# s
$ m7 }; C8 _, }( m t# q1 q- //display the size input+ p' M: T1 x$ v: g B
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);: c3 \- F) ]3 f, d
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
# p, H. {3 c, z1 H; o' o t8 \+ P - Delay.msDelay(100);
# z/ g0 k1 t) S7 Q$ g- B$ l4 y4 W; @ - LCD.clear();/ l$ h \' y) K$ v: u
- }
$ |& S: i; U% c5 I# h7 K
" R5 J9 ~7 U& V0 @, J- }# p4 M4 B% } L7 _6 e
8 A' ?$ [2 L, q; R5 V( t4 W2 e- publicvoid go() {# g( `4 H) e- T i( G! S8 q: P
- //准备起步1 h4 }1 v% E7 Z* t+ I: O1 f; j
- //wait for release
1 E( M5 I7 t5 A: a! K - while(Button.readButtons() > 0)' `) m8 H6 m$ u6 M* y7 f' ^/ |7 o
- ;
9 e' ^) u0 v6 d2 o& s. b; q1 Z - System.out.println("pressto go");9 m- e3 x6 d/ k+ F* V1 \& k
/ Y5 @ |4 h$ t- Button.waitForAnyPress();
% H/ j1 H# Z# m$ Z# ] - LCD.clear();
, w! J- f+ Y3 K r' m - $ O+ b& h7 d: {# m# T5 u7 a! `* f
- //初始化
+ z6 J" j; t+ b& M; g - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);6 X; w6 p+ | k8 H' U, I
- pilot.reset();8 j" F+ i0 C u/ W% n9 o
& o; T! Q( B y- Delay.msDelay(3000);
- R4 V1 D# f9 D) |& X
4 [- }* m! f: ^; V" G. G5 A- doublespeed = 10;
9 ^; c X4 q: V3 y$ w0 `0 K - doubledistance = 0;
* D3 J1 B& F+ _& N
4 N6 m% I0 }# f* g- //起步加速% f+ J8 Q- k* h- Q' b3 P
- pilot.travel(300,true);
) |$ P, e0 O( j" C1 b, z! J - + h. Z/ c4 _: I2 `
- while(distance < 20) {
* R& q" W5 T4 R/ y; Z: O { V- {( a - distance= pilot.getMovement().getDistanceTraveled();2 u$ d! W( n6 }4 c! u1 m
- speed= distance * 5 + 10;: R5 X9 U9 y2 L/ Q8 G, @6 H
- pilot.setRotateSpeed(speed);0 S1 g- O! b- v. S4 ~
- Delay.msDelay(100);
1 }3 {' \+ F8 @$ H9 V6 r, G - }9 f3 y5 S, `* s0 H* K0 `3 X+ W
- for(int i = 0; i < 10; i++) {
% i: q* ^2 C1 `, @" g) { - speed+= 5;2 J% }8 `! N% v3 W4 K
- pilot.setRotateSpeed(speed);
/ |8 [$ Y& B: l% k! b( B - Delay.msDelay(200);* d) N4 w. m0 v! ~3 u
- }* p# i" p, k4 ], |5 I$ \: ~7 i
- 5 L* ~9 i* g" @! D# _
- //TODO 减速
0 m3 z5 {8 \3 y" u; F1 w1 [ - 0 v) `0 d- h. K4 O5 n% B
- //停止机能5 p& A! V8 z9 g: A
- while(pilot.isMoving()) {
$ z0 s. z& g8 f& d8 Q# y8 H - if(Button.readButtons() > 0)
2 B; U" }% h6 A% W3 Y" Q! W4 {3 i9 u - pilot.stop();
2 H' O' e3 b" q/ M - }
3 G- B0 ]' a7 s7 [6 f - 1 O+ X; f4 u. J( u
- System.out.println("" + pilot.getMovement().getDistanceTraveled());
9 B# V! q, G4 _1 G0 l9 x) e i - System.out.println(-Motor.A.getTachoCount());- Z) N" V# }0 N+ G$ |$ ^+ M
- System.out.println(-Motor.B.getTachoCount());
7 s* T6 E. n" y - Button.waitForAnyPress();9 v }: K; W% d2 Q g
- }
' v. y- {& f( z$ Z4 G3 a0 Z( W* q2 ^
- I8 m% n9 x+ @& Z9 e: y- publicstatic void main(String[] args) {% @; z2 G. v r# C
- Straighttraveler = new Straight();
! I/ K) }* d' M5 v: u - , {: T; j) g/ u8 W/ r
- traveler.adjust();8 r' c. f" K Y
- traveler.go();" M) Z6 |3 p) ]6 j7 u, A
- }3 @) S+ C l: A: Z5 K8 R
- }
复制代码
; G. f& Y! J% u5 e7 E- J- v |