本帖最后由 hello怪 于 2017-7-25 22:24 编辑 - n4 D, _- Y; X9 v7 k: U4 C, T
% y4 U' V6 Q( p* i(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html & t3 y4 e, X6 V0 K6 ~
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: / u, Z$ t5 ~( J: [# C
场地. p/ `7 K. G) F' J. @: w
水平度和光滑度 在家里当然瓷砖的效果是最好的3 j. x8 \ p K; m. c
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
" z2 r* Q9 s- [4 S) S
: Q9 i5 Z/ h5 S- A0 ~6 a车子结构
m, i: W$ L& V$ @- @* i 轮子间距
0 Z) C8 r ~! Q" c2 \0 t 轮子间距越大越好,稍微想一下便知
- D2 N: p1 o: E 轮子大小
5 t3 ^! p7 [$ k6 H- g9 b 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
* l$ ~+ `: ]: A 随动轮的设计
1 k8 z$ D, C" T& | 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
, ~6 R _. R8 y0 J5 A/ ]5 v% U 重心位置* o$ R5 a, s6 C: [/ {( J) h6 k
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小/ }5 N8 z: T; m7 E: w {4 N
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大- V9 R1 r! W* V' U8 ]
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# s v! w2 h. x- B/ q
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动# }; V! E( T/ {! z% {! g$ F
9 I. Z5 A/ X d
控制程序$ a4 N9 k& j0 I( z( P1 C
运动过程控制1 R4 S/ D7 |+ `
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)3 y0 m$ }+ Z" K$ p" w! M: m
/ i, P6 i ] Y, ~0 f
调试与运行
% }& t ], |/ y, @ 轮子转速调整(车轮大小的设定)
! u* X8 h! g3 R2 x' F 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
( U9 e: r: u8 }9 O K 起始位置车子正方向和直线间的夹角
7 D7 K% T% |4 B9 g 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
$ K, U& c" M5 ^: u9 D( s, q' b: Y3 l! X8 d$ R+ R
+ j, ]7 L3 `8 X) s, b0 v
然后上源代码:
$ R5 x* D6 m2 O0 ^3 ^# K- importlejos.robotics.navigation.DifferentialPilot;
% I! \) l+ R0 l6 p2 | - import lejos.util.Delay;, m4 U: o( O8 X8 f L1 D4 e3 [2 J
- " J5 b' m) Y2 e) }( i6 w
- /**
$ K3 Y: ^ [/ f6 e( N- m4 P - *Robot that stops if the buttons are presses before it completes its travel.' _% ?9 T1 Y8 Z1 H8 X8 t8 ?1 t
- */
8 |! }% n' ]% P N2 O, y - 4 l) R/ K: {; j8 ~, P! ]
8 }* {5 U& D X3 c X5 T- public class Straight {8 C: p% v, V9 Y( m
- DifferentialPilotpilot;: |% ]" V) o* U
- doubleleftD = 4.3, rightD = 4.3;
. N+ ~* E; w/ i) E# u2 H - . T' {: _' ?3 j1 r/ k
- publicvoid adjust() {8 b# V: B* q8 x- w* K7 \
- //wait for release- K7 I# o1 L$ C0 e6 |8 l! l; x# m
- while(Button.readButtons() > 0)6 ~8 k0 X+ x& t8 g$ ]1 k
- ;8 u1 e. f: K, b* R2 }
- while(Button.readButtons() == 0) {
5 q% \) y: t0 \% C - //input size by adjusting the wheels
7 `$ j. d# g; y1 ] - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
4 E5 p' `2 A4 G( o. E - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值: P4 K) t1 R. T' b' R: c" x
& _! J8 i, I8 J) h- r- //display the size input
1 O( A# P. B6 k' f& E0 T0 d W - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
, E" v0 `9 Q6 G - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
8 @; |+ y& g0 I% g! D( x: F* k1 D - Delay.msDelay(100);
' E3 t) r, v) Q8 C1 o8 ~ - LCD.clear();6 D2 d! k3 }1 y q$ w8 b
- }
& L) M Y* x& _ t3 H - 9 A3 o5 Y; Z- h0 r E4 |" ]4 l
- }
2 W. @$ `' s- f5 p; r# ]
" Y9 q! D; h4 P+ z' B- publicvoid go() {* F2 ?7 Q7 b0 z
- //准备起步
! d. `- P* X$ @1 r) N% k# `' X/ l - //wait for release
8 m3 h" k2 z; e# [2 v* W - while(Button.readButtons() > 0)
! [2 `! `$ |7 e' ^" q1 \ - ;. V; V+ p& N" J
- System.out.println("pressto go");6 L9 ~# {; _( {; Z. ^
! r: \0 a- D4 K: b( q- Button.waitForAnyPress();4 N4 y! z2 c9 r5 J
- LCD.clear();; _0 S# K5 h7 R% ~) [( v
( d2 w3 I0 l: @% O$ z- //初始化- Y( ^: l# l# S1 e2 p
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
8 ]) r* S) w2 W4 C( W - pilot.reset();
/ t1 G0 B( m2 D# k: X/ z. d1 j4 J - 2 P8 Z) D( i+ m! G P
- Delay.msDelay(3000);: D5 ]- A3 X ]; B" s
- - |- M1 c. \( {1 D9 L# K! M# @
- doublespeed = 10;
6 u* L E. g k) u, e3 T5 R$ @8 X - doubledistance = 0;' D- T) K9 k. F% E+ S
% y& d, D% a7 _- //起步加速% J3 p: s. I% M# G
- pilot.travel(300,true);) s6 i# q3 N+ S$ H
( X3 Z7 U, _0 `; T4 u q4 P6 H- while(distance < 20) {3 D$ j0 R. W( p6 n$ |
- distance= pilot.getMovement().getDistanceTraveled();& t. S( e0 T. x6 W$ P4 B
- speed= distance * 5 + 10;
! g/ a! W4 b, p G V# @' ? - pilot.setRotateSpeed(speed);; t, v6 \3 T* W# t( S" L6 i" _
- Delay.msDelay(100);
& K$ Y+ c7 [0 G* f" g- G - }
1 G* b9 K( y2 @/ F' J - for(int i = 0; i < 10; i++) {
1 N0 R1 Q) o/ F$ K - speed+= 5;
9 j2 {* Q G3 [9 C7 Z5 b. j1 z2 v - pilot.setRotateSpeed(speed);
5 h$ G4 q/ e! I' {: I h - Delay.msDelay(200);
6 Z3 @% g% ?4 L4 ^ - }: G/ R, f H7 A1 D! m1 T! ~/ G
E- [" s! f+ O2 P- //TODO 减速
4 l! B! l; O; H' G! d. `' M' M; I - 5 e* J' q4 Y6 {* V4 m
- //停止机能
6 G0 `- O& Y, O) H0 k6 G% y9 S e5 X" h - while(pilot.isMoving()) {
/ S- B6 c# A9 c- ^; B; G8 G1 s9 Y - if(Button.readButtons() > 0): e8 e4 d9 X8 m7 X1 ^
- pilot.stop();
3 ^2 b% u# A, w - }9 Q1 E. ~. ?- b( v% t
/ ~: T7 w& t4 z- System.out.println("" + pilot.getMovement().getDistanceTraveled());) \/ R: [8 L# K+ m
- System.out.println(-Motor.A.getTachoCount());4 _& o7 p( [; r4 l% w" S
- System.out.println(-Motor.B.getTachoCount());+ I( V0 d! A" U! @- ?) {% F
- Button.waitForAnyPress();
: e9 u8 ]* u! w; H9 P/ @ - }
* d' q8 A2 V( [9 c. }6 Z! t) Z
" q. E) v2 w# [4 s4 |7 ]- publicstatic void main(String[] args) {$ N4 o% e; u) L2 R d) \+ A1 I& ~3 {
- Straighttraveler = new Straight();$ W" L9 l2 m* s; i0 \
- & [" G; X7 l& x$ X+ W' p' V
- traveler.adjust();
2 V# j: |9 C8 H - traveler.go();
. t! U0 n" G; h7 e/ R9 F. b - }
' m& O9 K$ N- `8 i- s; T. \& v - }
复制代码 $ _8 _% R, I3 [$ h0 B9 ?
|