本帖最后由 hello怪 于 2017-7-25 22:24 编辑
5 o: Z; B6 @* ] S) [) \! w0 e! v1 R9 h. t4 W4 x
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
" O7 |* }5 y7 t" z" V9 d* B; R
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 0 g# `3 s+ |* j! D7 ?& y8 V
场地
6 D$ R: y. V; ^9 z( i( _0 H6 K 水平度和光滑度 在家里当然瓷砖的效果是最好的% R5 r1 y8 `$ J' W, t7 i0 k
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
% ]' B- _: n; s9 R4 ?( V8 d7 X# Z" @& ^
车子结构
0 o' J- s+ Z/ V$ m* X 轮子间距
1 m2 J6 K& |. g S/ t 轮子间距越大越好,稍微想一下便知
- t1 ^! u: K4 K. N p; ~ 轮子大小8 _. \, U6 a' N# A, o* ?
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)! P/ a( r, i) t
随动轮的设计. |' A: e( O- U. Q0 m5 s) R) x
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响1 Z0 }% J$ B4 e& f* i. ]
重心位置
8 Q) X/ L, p7 D( P 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
' X2 W; Q# A, `; m 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
0 S# Y5 x. a0 j' B 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)" H: ?3 a5 i$ V: i1 |! K* X: ~
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动% k+ ], o3 b% J3 _
: i9 @3 ]/ u" n$ n) U& h+ {7 o控制程序& e; ?; B) I3 K. k: c2 I* A. Z
运动过程控制
8 t4 s7 V# v! h 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)( p* M) ?) d6 l
9 w7 B, a4 E i- j调试与运行0 @/ f* d* Z8 Z4 T& g
轮子转速调整(车轮大小的设定)
9 M `8 V! R$ z% X2 M, G0 a9 H 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法$ \& ~0 @7 D5 P ~+ D, f, l( T
起始位置车子正方向和直线间的夹角! ?- M6 u! Q9 T7 |4 T3 P
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 0 T, G. l1 I# M
* V V9 |3 k J1 L" _
4 X# v6 \! Z3 C 然后上源代码: - ; G; p; v" V7 |0 U: d, l
- importlejos.robotics.navigation.DifferentialPilot;# `( K% H |5 D
- import lejos.util.Delay;
$ x, K- t$ Y% |& K/ \- }. ] - . b w, H" f; }8 c4 T
- /**" D- r% Q0 Q& }
- *Robot that stops if the buttons are presses before it completes its travel.
6 B: ^/ G! k3 J/ ]$ E. L m - */; f1 U& P+ T5 Q$ F- O {( g
) K. ^; k. a/ s ?; E4 x& P8 h. W
3 Q. @& o9 C# k/ e" `2 F- public class Straight {
4 E( L2 o7 v. w: E- R" } - DifferentialPilotpilot;
: O, b/ [* w0 n5 X - doubleleftD = 4.3, rightD = 4.3;& d! O0 v: r. ?. D
- - w1 Y' p& m: f8 R9 k
- publicvoid adjust() {4 Q4 E/ J" t& l/ m, c
- //wait for release
& ?( C& z# Z& U - while(Button.readButtons() > 0)6 F. N0 z9 M: N$ c2 @8 J- K% e
- ;
) E! A- {4 h( J* e. T2 _& B - while(Button.readButtons() == 0) {
' `& a; b5 {8 [1 k - //input size by adjusting the wheels
. x7 `# f2 y* z) p5 t - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;# J: o0 \ n2 a: {! {8 X
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值" y3 r( |5 i; N! D4 G$ F) `
- + J# Q6 N. y. v# x
- //display the size input5 {, v4 X8 s8 f2 I: O. O: U
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
$ D. Q% T& c/ N8 h - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);) `1 v/ l9 |6 A
- Delay.msDelay(100);* j7 Q0 v2 m! F0 ?: z9 P
- LCD.clear();6 I8 o$ |- j# d/ H
- }; ^& S% w: t/ d* _
- % [) |, j ^! Y. h( ~! V6 R
- }
+ s1 A- a" N% d3 w+ r% F7 b H
7 D3 e% O+ w8 _; y8 C- publicvoid go() {
4 k$ R0 H2 J5 q/ A1 ? - //准备起步% X, ~; [/ W9 E/ P/ d
- //wait for release5 T* ~4 _( b9 h$ Z: |1 x. y: q
- while(Button.readButtons() > 0)
) d! P8 G+ ~! _4 E7 ` - ;9 \9 J R {' Z
- System.out.println("pressto go");
6 T6 L; P$ r6 M9 u+ A2 P( R) L
2 o! t) I- r, d' Y9 ?* p: z- Button.waitForAnyPress();. b# W! H( S, [, L
- LCD.clear();; ^# L7 ~2 M- T" K0 s6 n G5 h
- 3 {" K; P; G7 C1 r3 R% \
- //初始化
. p$ A/ _, |8 Q3 D ]. p2 v - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);$ b+ Y: V8 c/ P' E
- pilot.reset();4 O0 }5 W' o, f: k4 K* c4 d
- / `4 I# a/ ~* C4 u# d
- Delay.msDelay(3000);
+ V( O+ g( K/ C2 T" A2 Y - % E- Q% r0 J P" G' b5 _) K* F% P9 m
- doublespeed = 10;3 A0 u, v3 Z- h) W3 w
- doubledistance = 0;0 A: y. a. U, a
- 9 y/ q3 q9 \# s$ C
- //起步加速. ]) r4 Y' |8 o% {. E
- pilot.travel(300,true);. A5 J2 \: c9 `# i
- 4 u8 P7 g4 L( c1 B! |, n
- while(distance < 20) {- T: p% r& u' t/ b# K7 m( F
- distance= pilot.getMovement().getDistanceTraveled();
6 K P: V" y4 ^3 l" Y' T8 x1 Z+ ` - speed= distance * 5 + 10;
; {* g: a8 Z7 B) z - pilot.setRotateSpeed(speed);
5 \( ^5 y. e$ d6 M; i - Delay.msDelay(100);
: R A$ t; i: [3 m$ @ - }
1 f! m+ [; b. c j/ i s) J - for(int i = 0; i < 10; i++) {& \! m: @: ~0 \$ @% X v$ \
- speed+= 5;1 l% G0 }- |. m( U( B3 I
- pilot.setRotateSpeed(speed);
$ W4 B$ x4 E' T- m: Q# a - Delay.msDelay(200);! a, t7 s! F) Y/ u" |
- }
+ r# e7 U8 f, g* z& I7 f3 s5 ` - # X% S) ~6 n- Z! t1 {+ \
- //TODO 减速
" G/ R1 B6 O/ ?4 \ - G& }! d" Z& n1 r8 I
- //停止机能; I0 |* x( J" P, |. {8 q; I
- while(pilot.isMoving()) {4 C( j% R. o7 f' N
- if(Button.readButtons() > 0)
! Z9 S. l: l, P0 B' l3 |( e1 W - pilot.stop();' w" Q# e7 D3 q0 d3 {: q' D
- }2 u8 d L) V& j! P0 O+ ]: u
- $ R, f; v/ }2 M5 d: j/ ]" b7 r
- System.out.println("" + pilot.getMovement().getDistanceTraveled());) G* k" O! r, O) W3 Q& k
- System.out.println(-Motor.A.getTachoCount());/ C9 o1 l6 U/ p, @7 u5 u, l
- System.out.println(-Motor.B.getTachoCount());* l7 g* a% l4 E- g" j
- Button.waitForAnyPress();8 t! d8 t% ^1 K8 e n5 @9 x
- }
5 r+ V9 P9 F+ X% Z* |+ J- e - 4 b" p- r" c3 \0 R* K+ R
- publicstatic void main(String[] args) {5 M$ H8 {1 [; H+ U' j2 E8 F4 I
- Straighttraveler = new Straight();
7 y8 F. x6 I H! T$ w4 K - : l/ A$ U, V7 |4 ]8 F7 O0 l( a4 ~
- traveler.adjust();% o1 B+ c" I; K/ `: H
- traveler.go();
9 W- R2 _8 j1 a9 o - }/ N+ ~, _( @" A4 ?+ a
- }
复制代码 # @7 U5 E# V6 A( |3 O3 C
|