本帖最后由 hello怪 于 2017-7-25 22:24 编辑
1 G8 ^! J2 a3 O) t
* s# ^3 S. Z- s- ^2 j( Y(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html % S, z* \+ Y; s# h9 ]. F* ~
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 1 u9 E4 u' T* i5 `. I* X" u8 k
场地
( M3 S( ? S3 x" }8 o. p* {4 r 水平度和光滑度 在家里当然瓷砖的效果是最好的; g, D3 x$ H; m {
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
" n2 H, o/ B$ |7 N& k1 R% {& o# r+ }1 ^9 @8 ~7 l# V
车子结构
) O9 m( i4 H0 ^( p% W4 ? 轮子间距
0 |1 l, M6 e Z! ?( P 轮子间距越大越好,稍微想一下便知
4 D! F$ e" i5 o( x 轮子大小
1 D8 K+ r4 t. K8 y 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
0 u" C4 n$ c1 m% a4 ]6 U2 N 随动轮的设计9 m. r/ a* B R6 X+ m7 o2 j
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
; O0 ?) T4 y3 y1 E" {5 | 重心位置0 c0 s; Z0 Y5 W0 B7 k& S6 Q& g
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
4 U+ \) l) y; L: M" Y( H2 z 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大. t# O$ p8 J8 \6 P+ N
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# r3 ^0 y; k8 C* V
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动# n4 ?- k& |/ x: I& ^7 U& O
7 b7 t4 l" W4 O6 p, @控制程序: U9 c% i8 v& G" S
运动过程控制
+ { W2 C3 c9 `* o) l3 X 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)! }1 u3 O7 x# p& i7 q: @. a
' M# Z+ M D+ r3 S3 d
调试与运行/ z0 _8 ?5 F* b
轮子转速调整(车轮大小的设定)
/ I+ |$ F7 ^7 y0 c1 I: _ 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
1 A9 H+ v W7 ?# ^ 起始位置车子正方向和直线间的夹角
7 w" ?$ |5 N% L( `( d 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
: `9 \9 j6 F0 f& W- P" @) J, e) O
8 ^ a3 X# i4 x8 ^0 `( v! c1 @4 Z$ n+ d% Y4 B
然后上源代码:
* `3 v3 u+ x: l N" ^- importlejos.robotics.navigation.DifferentialPilot;( u' T9 |) u+ w- H# }* t! `
- import lejos.util.Delay;
( `1 F+ j6 h0 r2 w+ M0 I - 1 ~- G5 d' n* B4 _
- /**
6 O2 c, C. Q1 v" s) E. U) H8 [7 B - *Robot that stops if the buttons are presses before it completes its travel.
* _" C. D K+ g8 Z: F - */+ Q% r5 B0 t5 D$ B
6 z$ \4 r. {# J/ B
7 c6 v5 t3 x9 \' Q" w- public class Straight {' |+ i8 \0 o( _' s3 H7 z' P# s% n) t+ r
- DifferentialPilotpilot;
# L7 @2 w7 G. o" q2 l - doubleleftD = 4.3, rightD = 4.3;* v+ y3 u1 z( r/ o0 j1 L3 U! r- L7 N
- * l2 Q3 w3 i; T1 C9 \
- publicvoid adjust() {
5 T) b* P. | }% @. k1 V5 a8 G - //wait for release
) X/ P, K5 ?, x: C$ h - while(Button.readButtons() > 0) {/ W2 f& P4 N! p; r6 }/ n: s
- ;2 Q T5 P. L) U( Q) l1 G
- while(Button.readButtons() == 0) {6 M. M+ Y9 O/ G8 A
- //input size by adjusting the wheels' G! K$ Z6 h, R7 y- G% s
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
; z B" m' ]2 S; W& i& e3 @9 e, _ - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
3 X: v& o4 q- O" n, k. O
3 M6 B0 ^( v0 t( {7 P- //display the size input; n1 S0 j1 U3 ]; A/ N' R
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);6 D( q/ A8 T2 ]5 \
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);) {( i! W! U+ J
- Delay.msDelay(100);
! i7 H- D5 l( [2 A& S7 a5 }" D - LCD.clear();; B" D' s8 N6 h0 N: U* H
- }
# {0 k u/ G# h! R% a
; I2 F" A+ d9 F/ P! R( e- }
% H ^" ~5 q6 h% v8 [ - * `' F: U# V, ~ a- H
- publicvoid go() {' R | u5 H) l3 K6 d$ O8 B
- //准备起步; H5 Z0 ^7 X1 u! Y1 x
- //wait for release u8 ~/ l4 U; t3 Z. p: e
- while(Button.readButtons() > 0)
( Z9 }7 ?" }& |5 D - ;
0 d( U3 V, I9 [, e - System.out.println("pressto go");9 Z% G! ]* Z& z7 ?$ c3 P8 j* @
- : @6 h* j$ E& D4 Q! D
- Button.waitForAnyPress();( }( E2 m5 @* a1 v q* P, J* b
- LCD.clear();
5 w1 f8 x7 z `4 B5 p' G - 2 j0 ?2 W# }; M, @9 L X2 y! }% r- @
- //初始化$ _4 {. N& s* h+ d( Y
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
5 B7 z* F# n* `2 ~) E1 \# Y - pilot.reset();5 C+ l# p! |2 T! W4 M- N
7 C }# N1 R7 O2 I2 F5 L2 x- Delay.msDelay(3000);5 N) M8 W& e$ |9 }
+ i0 k4 g/ K) d8 w' D- doublespeed = 10;
$ ]0 x% A. o; l2 j7 v - doubledistance = 0;
) m$ n/ W1 R" ]4 K$ o% U - 8 U7 X& Z) _, `0 p( X
- //起步加速. g& X1 I K, m. D6 P
- pilot.travel(300,true);
S8 t- q; b; x, ~ - 5 Z! M9 i" f( J8 [" S% U
- while(distance < 20) {( T3 P* C5 c% _& o
- distance= pilot.getMovement().getDistanceTraveled();
' V- A. a ?# V/ h; e - speed= distance * 5 + 10;, K8 o5 k0 d4 y+ _ K4 c1 O2 m
- pilot.setRotateSpeed(speed);: g/ s7 E( w: S4 @: d( i
- Delay.msDelay(100);+ ~3 W; B+ l' S- U; ]* ]7 o! M, m
- }+ L, d" h; T% w2 z: U" @
- for(int i = 0; i < 10; i++) {9 Z; {- g1 p# G% l( P
- speed+= 5;
& H; k$ u' {6 E; i% i! ]# }; b) N - pilot.setRotateSpeed(speed);
/ A: J( e- W, Z, R* l+ c2 @; I7 ]3 z: u - Delay.msDelay(200);( e, W9 @% w8 ?7 x7 d4 m$ D
- }
% i+ D9 e) J2 j/ [ B) D - ( a0 \7 I$ O# A1 l& ]4 S1 ~. H
- //TODO 减速
4 @; F& H3 o1 Q - 5 R( o' `8 K4 N5 F$ t
- //停止机能) {, R% |( }: h7 ?0 i/ O6 N1 s$ P0 W
- while(pilot.isMoving()) {+ i+ E, g$ N( R; D
- if(Button.readButtons() > 0)
# `9 H3 u1 [! q2 H - pilot.stop();5 Z% X8 G! ?: `% Z; C8 X9 U
- }1 ^4 P# s, R; j c. e* g; A% u. m
% @' B* j7 F& y) o+ y1 ~- System.out.println("" + pilot.getMovement().getDistanceTraveled());: W' j" W+ p e+ b! n/ S, t' I
- System.out.println(-Motor.A.getTachoCount());! X3 f0 d9 q. ~5 |7 s' j
- System.out.println(-Motor.B.getTachoCount());
1 ]& [! M9 ~* D6 R0 Y - Button.waitForAnyPress();
3 s, l) |/ @0 b0 \, O4 c( W - }' S, g. N0 j# ^/ x; m- t
6 y4 s( l3 Y, | ?8 A1 J" T; g4 k- publicstatic void main(String[] args) {
" j6 o3 z! S% b. ]( I, b- C7 e - Straighttraveler = new Straight();
' L' U& @/ r: Q) q" c" w - ' {) M% G+ r0 C2 b6 C" r
- traveler.adjust();- d, g/ I6 u/ t
- traveler.go();9 X- w5 ]7 L5 S5 u) i
- }4 R" H1 P, E! A/ r9 H( a& `: R* h
- }
复制代码 ) j2 _: _ D9 S4 x
|