本帖最后由 hello怪 于 2017-7-25 22:24 编辑 + {. D+ k$ Z6 @6 w: m" P5 S/ w" J
9 T, ~# j; Y5 u3 P
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html . p4 s( s) o. d' b) d5 `
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
; [: x* I' ]! E+ O) s" r- D场地) A2 X4 J4 t- p$ q6 K- p' w
水平度和光滑度
在家里当然瓷砖的效果是最好的! |' n0 O5 f# g$ _- m* r- I8 T
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直+ F/ C. n' [# F6 G" s
4 e& y n; l r5 @& D' z车子结构) j6 ~) Q6 C4 w9 u
轮子间距0 K8 e* u" m$ r9 e8 C% M+ ~
轮子间距越大越好,稍微想一下便知1 {) Z% B4 `% N* U
轮子大小
$ k4 K& B _* K% h6 J! @# W5 V% ~ 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
; r6 P! L+ o! S. E3 h0 Q Q 随动轮的设计8 `. `( Y: y, R$ g _( g
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响! m: I# c6 X, r$ d
重心位置- T. `% x9 I2 \
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
' F }4 B% l1 g5 K 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
" p* e' b" j f7 m' v5 ^) @: i 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)$ M2 { O+ n5 }) x8 w# B6 D
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
. S7 [, t% C2 t# U9 T% i; v6 o% M
7 c' [, e/ R( `3 x% x控制程序5 E# i3 _- d' n$ e* q
运动过程控制- S3 s. P J+ t% Z/ b
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)' m2 i+ N( i+ B5 L" x
6 y y4 N9 c5 x' w) D# a5 b
调试与运行' r4 R1 M0 x/ n5 H0 ]
轮子转速调整(车轮大小的设定)+ x% L" o" O! p
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
4 ?* w" i4 s2 p! ` G9 A& R: J& @ 起始位置车子正方向和直线间的夹角
* D. [3 z* D' Q+ | 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ) K+ V% r; K* y: H1 I
) z" R, d( c. @7 c$ J
7 v1 |2 ?( \3 u) j 然后上源代码:
, s# c8 j4 G) d. [5 }- importlejos.robotics.navigation.DifferentialPilot;8 Z2 V, Z0 c- E) L5 O
- import lejos.util.Delay;
9 V# o# k1 y6 l( b8 d - . c6 _6 ?3 K. d( l8 ^1 C
- /**: `7 @' z# D5 I; q. f7 I
- *Robot that stops if the buttons are presses before it completes its travel.0 Q4 x% v; e: S3 V) b
- */* G7 T+ S1 |- a" s1 R- b2 N
. h4 `/ S' _* }5 Z& L& d" y+ T
% [" n+ {( Q! w! {9 ~: j- d" F: B- public class Straight {
+ O( W. S0 L" K4 D4 F - DifferentialPilotpilot;: ?% P2 d- g0 n7 N: p I
- doubleleftD = 4.3, rightD = 4.3;
" l+ E/ Q( Z: a" D) k6 } - ; O6 G; K+ o. h
- publicvoid adjust() {' H8 q( {( `" n: f8 g7 ^ F
- //wait for release
. Z. e4 R% @3 h+ I r: ^# d/ l - while(Button.readButtons() > 0)
. o( ]. a- U! c9 @6 Z, R - ;
" j; U. s, V9 n# A - while(Button.readButtons() == 0) {0 a1 M* A/ g9 `% Q; B/ s
- //input size by adjusting the wheels
0 x9 k( p# H9 }0 P) } z - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;/ M9 l/ A- f0 O
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值+ f3 z3 K/ G2 j/ X
- 4 f8 T3 y! j5 I1 ?! A0 v! {( B
- //display the size input
( V0 x. a: m7 ~ f0 p* h - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
- H3 O: |0 h! ?6 ]& Z4 E8 M - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);% d& ]! ^1 `( p. m' t' d
- Delay.msDelay(100);! m8 q( `% ?, u+ R5 P; h
- LCD.clear();8 I6 @1 O5 w) C) o4 l1 S. n
- }5 z: a! h/ G! S P& c& |& C
- - B+ _+ P9 }. X* N" t9 ~) v
- }4 P4 x, \/ Z" O# H# a5 M! R
- c2 C2 i: L, ~8 f: ~! e- publicvoid go() {
5 y4 l- v; i) Q( j - //准备起步 X- _. B9 P$ ~) K2 S
- //wait for release
+ a0 v3 g% a4 j. }9 u1 R; b - while(Button.readButtons() > 0)4 q3 w2 t/ f |! \6 h3 T
- ;
. X4 K. N6 A2 Z! H B3 l - System.out.println("pressto go");6 L/ E7 x" N8 v' S7 {2 Q; r
- ' R [ f, e) d2 ?1 r. j
- Button.waitForAnyPress();/ m: m. P1 H/ P9 g u0 q' a2 V7 h7 c
- LCD.clear();
* h" B3 k; |* V" z& O+ w, W - % \4 ~# d. [. q/ q
- //初始化& H# W) M6 H5 @: J& C
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
5 r/ r7 G- ?: `- `6 x - pilot.reset();
3 O$ A( Q+ Z* H$ e% x! A! G
, B1 L" S5 w7 r r& N6 z, Y- Delay.msDelay(3000);
; J7 j k+ [5 H! V/ n - 1 Q# H+ \ U% ~4 [; c
- doublespeed = 10;
( N# C4 X8 a3 T3 f# i, q - doubledistance = 0;" V; K2 v$ ?, f& a- H; S- d
) p$ [. j9 }! W- //起步加速4 d$ Z6 L' E* L& m- m7 x
- pilot.travel(300,true);; O2 X; W/ @8 E
9 j$ [( C7 q3 t4 I: c) v5 T, p- while(distance < 20) {
. a: c# H4 r. z/ s; c% Z) E - distance= pilot.getMovement().getDistanceTraveled();
4 t ]; o8 o1 i0 t5 a+ x: g - speed= distance * 5 + 10;- I7 A% T2 ?; W7 X1 k$ S
- pilot.setRotateSpeed(speed);! p5 h- b6 e- \5 j, H- O
- Delay.msDelay(100);
) z: O4 P; B6 r2 i* j$ z - }
* D/ H) L' O1 g# P: u - for(int i = 0; i < 10; i++) {# { O2 \- w( l* [* i
- speed+= 5;
' v& }4 F3 F! s" J - pilot.setRotateSpeed(speed);5 r% r$ h) n, `$ g1 y
- Delay.msDelay(200);
& D) w$ y, D. ~( c. I - }- s$ Z" U% \) o; ^' k
" G6 O2 w4 o6 L. \0 `+ e- //TODO 减速
- X& l: w( B! ~# A) l - 0 ` l5 _! T, b6 X8 `8 Y& U5 b
- //停止机能$ @8 M4 M. m) f+ `, l2 |: S! Q
- while(pilot.isMoving()) { E5 N3 n/ N* p! y. B, {
- if(Button.readButtons() > 0)
7 G8 M) D1 s6 \1 V9 o7 W& z- g% } - pilot.stop();5 G7 F/ C9 ?# h/ I
- }
D& Z: C/ k; h/ } y6 z+ ^
F) z0 b8 `( n+ {; G( Y1 n. a- System.out.println("" + pilot.getMovement().getDistanceTraveled());: Q$ s- L9 P7 V$ T2 A$ Y+ S
- System.out.println(-Motor.A.getTachoCount());, [$ J/ J" j; u; Z+ Q5 C
- System.out.println(-Motor.B.getTachoCount());2 c6 R: g; S- @9 @
- Button.waitForAnyPress();9 t- `% n& g5 b5 A+ A! W, [( {
- }
7 M6 [2 \& B& ^8 }! o, m
4 U1 F( W& S7 `0 p! Y5 B- publicstatic void main(String[] args) {
) b* c0 d7 z2 ?) l) k1 }' ? - Straighttraveler = new Straight();
/ c0 ^0 B' o5 a! t, S - 4 \; o+ E+ q: l1 D: H+ J% d
- traveler.adjust();
# y# f3 i5 n) s* ?( r2 X. K - traveler.go();
, A# h# _1 B" I4 E+ t$ `: H6 ` - }
8 [( ]/ [" I% v - }
复制代码
: b0 X0 D+ A3 H: q" ]7 x/ ]3 |) I |