本帖最后由 hello怪 于 2017-7-25 22:24 编辑 : P' o2 k: \6 n& _7 P' q
0 K0 ^; [: x$ o1 `
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
V2 Z- L. G( G) D# K
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
! C- t8 @% ?/ L7 G场地1 A" c) ^. J, L- M* r
水平度和光滑度
在家里当然瓷砖的效果是最好的
) C6 H0 J& Z2 ^: n% ~% ^# w9 a% a 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直- `- z" ~( P9 O/ [) z9 b% ~
$ e. k" d3 v7 k, Z! {3 ]
车子结构
z. F' c! N5 r6 } 轮子间距: c+ s: ?) _& N7 \8 p5 I
轮子间距越大越好,稍微想一下便知
3 W' Y& N, m0 ] 轮子大小; m \* x" { A: U( Z. t$ }: W1 Z
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
- g$ h2 w- J" l( M- z8 @( e" B 随动轮的设计
! U. r+ c1 j! T: P 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
: B% l# K7 Q8 O& `: s 重心位置
- {' u" s0 V# W* @1 m7 | 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
$ r9 r9 d7 b0 H! k# f 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大& C* `7 a& V+ {
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
, X, v* m" U E/ p, @ 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动, t& b5 i5 W) w2 i
1 I6 D$ x% d' Z8 a+ Q f4 w控制程序
0 l7 b7 }* o$ j/ g 运动过程控制
+ S0 ]( F$ e% e& I) P3 ^ 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
2 C# q% ?. r4 h% V3 K w' a! {6 F
9 k/ a c# c0 w调试与运行8 P4 z. o! C- ?6 r# N( _3 Y; Q
轮子转速调整(车轮大小的设定). q$ ^7 S4 f4 l N! g* j
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
! E8 q$ w" w Z- { 起始位置车子正方向和直线间的夹角, M$ C8 _7 e+ C* `2 ~, Q
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 s5 I6 F1 P! M8 E8 X
, P: R- X; F; |' Y, H* R% R2 v
, \0 W& r1 {" H: \8 p, N& U, S% K
然后上源代码: - 6 j% Z/ B/ p ^+ B J v4 ]- \! u
- importlejos.robotics.navigation.DifferentialPilot;
0 \& l$ r( U. B - import lejos.util.Delay;8 A. v4 l* M. \! }9 h; S7 }
3 B+ L# G" h8 g; u- /**8 y+ r: ]- {. C4 o% d/ p/ [
- *Robot that stops if the buttons are presses before it completes its travel.
1 j- L2 z9 a* p& r) m1 K - */" \* G/ _; ~: b
- 0 I. J3 u- U! {7 B& H
- $ M9 g/ K% S1 d
- public class Straight {
$ [' B0 e7 f4 S6 h# g - DifferentialPilotpilot;
( |/ P$ t5 {% R) N - doubleleftD = 4.3, rightD = 4.3;
7 k' w3 Q6 _& b5 X6 d6 P5 i2 ^
* \# f( y" m) y- publicvoid adjust() {. U, M: p, K7 d# m6 I$ b
- //wait for release# k6 t k; @+ o- F1 i7 g
- while(Button.readButtons() > 0)
/ _- T) {% ?- H1 e( ^% M - ; i" I! q: d5 l5 q
- while(Button.readButtons() == 0) {
4 l5 }& I1 }: X( b - //input size by adjusting the wheels2 ~& ^- w4 r8 F4 z' }1 k. [
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;& u8 p' g& ]8 g) a* }0 B( U
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
- M4 k1 L9 X+ r5 | - 1 X. Q6 P. g) @. m3 G. ^. [! E) t
- //display the size input
8 k7 d9 e/ s( {2 Q- h, Y - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);! G1 E ^7 w7 x. r* Z- c0 w
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);' _# u, W' t+ e
- Delay.msDelay(100);
. ~" N {' e. M5 W$ e - LCD.clear(); C1 z! s/ P7 O1 u- H" }- x
- }5 d4 `# E' F6 m& ^; o( |
- ' _/ v+ T& I0 w5 s
- }
I" S. X }' t$ V! W - 7 w' L, m. G$ e% N
- publicvoid go() {* e7 Y/ h8 d: t, b
- //准备起步& Z( w; Z& X# A' {& S& k5 }
- //wait for release4 w' N; t* z+ w
- while(Button.readButtons() > 0)6 S% } R. I! l# Q: L' b
- ;4 c: h& q* z' d% D+ U" ^
- System.out.println("pressto go");
( }9 d5 S. \" y2 }/ a - 0 o8 I9 r% Y& c4 y( E) q
- Button.waitForAnyPress();
3 w& s; Z0 q3 N7 ^) E9 N - LCD.clear();# q7 X: w/ G+ V* S; T
- $ X1 C2 D; i) j( H
- //初始化" s" ]" d! f" g- I0 a
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
! v3 r$ y! O# c& h3 y - pilot.reset();
# R5 p6 Z2 }: L5 D+ c3 x - . d' X$ y! y& d+ \+ Q4 m9 T
- Delay.msDelay(3000);
" Q* d3 l. f7 X9 u
" l1 @/ a6 r& ^- |( @3 [/ n# K- doublespeed = 10;
7 V6 J# w, a7 B* j* l5 B - doubledistance = 0;
, j0 _& `5 l* h - 3 m& d) l ~2 \8 ~: ]) L9 \; t
- //起步加速
7 X9 }' x: v- ~& I6 t2 E! l - pilot.travel(300,true);, v$ @2 y/ n7 \
- * q4 @+ }7 v4 q5 i2 l
- while(distance < 20) {
9 W. ~! j d0 G5 X4 d0 g - distance= pilot.getMovement().getDistanceTraveled();
3 L# b: _3 o2 `; _" U - speed= distance * 5 + 10;. F1 V/ D: Y0 v A: ~
- pilot.setRotateSpeed(speed);
& _$ b3 K3 J. o6 G1 K+ B' |8 N' A0 G6 m# y - Delay.msDelay(100);
3 [+ _4 h) m- e+ c/ N9 S" f - }; K: [( j l" ?' n% k3 z5 ^" Y% Q
- for(int i = 0; i < 10; i++) {. o, z; U4 h6 h4 D$ O
- speed+= 5;
! {$ m4 c, v D0 D$ r, m - pilot.setRotateSpeed(speed);1 d" r& R7 s: F0 s6 m
- Delay.msDelay(200);
# c. [3 P) R' O) s; R' x - }
6 ?/ E$ ] \# Y7 S! p - 8 [+ P) B6 i. a8 H, p
- //TODO 减速
$ c7 P9 i! t/ f2 W4 S; d* y% {& X7 e
3 \2 R% L q8 A3 @- //停止机能
; @; q3 P; V$ `; O% r" C7 W - while(pilot.isMoving()) {6 g. T# L( u3 e* \8 W
- if(Button.readButtons() > 0)4 l' }+ R/ \ A4 L& y% c# }
- pilot.stop();2 x) K7 \2 ^2 Z8 Z
- }
3 e' N3 ?, w4 F9 u& R0 X+ n! F
9 ?: k4 k: O6 ]$ \' @8 w2 y/ W- System.out.println("" + pilot.getMovement().getDistanceTraveled());- Y8 y$ P' O d
- System.out.println(-Motor.A.getTachoCount());
3 l" z" k; ^. g8 p D" {0 R - System.out.println(-Motor.B.getTachoCount());
' }: j' p7 T4 s+ v+ H - Button.waitForAnyPress();
' [! _: K7 z5 A- @9 M& R9 a - }9 Q6 J0 e% R+ s0 }" E. i
3 p2 g1 W& I. [- H$ X8 u- publicstatic void main(String[] args) {- E7 L% X$ d3 _+ i9 k9 j
- Straighttraveler = new Straight();
/ ?) e! K+ v" ~ {0 i
) P- ^/ L g5 q( w! t7 J" q Q- traveler.adjust();
3 N" S2 }2 Z9 v+ z8 R% Y3 s1 u - traveler.go();' K' K' f0 A3 [1 S/ `8 @, e, r
- }4 m9 j& u: O. Q
- }
复制代码 |2 I* q& M; o7 G: w2 G' l+ B( s
|