本帖最后由 hello怪 于 2017-7-25 22:24 编辑 4 q8 Z" C1 m8 @# o
0 W l* X: h8 r f( c5 L2 \
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html ; j8 u* f. k# V2 y
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
) Y$ v9 G: ~8 G5 {* P& b场地0 Z- f9 j6 y5 y$ m3 H) v# w
水平度和光滑度
在家里当然瓷砖的效果是最好的* V# q# D+ K' H: H5 X9 p
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
1 S' n+ e" H; ]) y
7 t, ?7 ]0 ~1 y车子结构
5 r" q5 t* Q$ ?4 c! L% o6 K! | 轮子间距
( i. j7 _; Z& b 轮子间距越大越好,稍微想一下便知1 W8 [+ S9 `; k
轮子大小
# ]9 G( w6 Q, X4 N2 b. Y! ^ 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
* ^( M1 p& H, p' g9 K. b 随动轮的设计/ c, k4 K& W% ?, n
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
5 i5 \" z. W: P ^) b3 A x 重心位置6 p7 `; `8 p: l3 t! R# h( ?( Z
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小) I7 Z* k9 s c* `1 N& g, {) y& g; G
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
1 x% b; [& x' p 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
& ]( a/ c: C% F) M7 |9 r/ S8 b 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动5 @! r1 E1 m3 K$ M* c+ ^% z+ _
3 y# V. @4 E5 Y; T1 q! M控制程序1 M7 d; w% Z w. o
运动过程控制. ]7 l- {' `" j* H3 s. e' [$ `
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)$ k( r6 {& b2 q9 Z. J' K, [
; a$ X9 h4 z# \; U; }调试与运行
+ e4 i6 E3 M( V 轮子转速调整(车轮大小的设定)* \- ~' X s5 |/ Z
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
/ A( p% j' N7 d3 b4 k' P4 y 起始位置车子正方向和直线间的夹角+ \0 S3 R9 p1 T! {1 u
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 # k; S7 w5 l W8 ^% Y" e
: _7 w7 |4 J# Y/ m4 r5 v1 [
9 F9 O J3 X8 [7 `% x# Q- a n 然后上源代码: - ! n/ w* R/ q; o0 V, ^
- importlejos.robotics.navigation.DifferentialPilot;' ^, _, H; Q& l: a% Z& e2 z0 J
- import lejos.util.Delay;* O" ]( Y, R4 \, }1 P4 j5 }
- 8 z7 y$ x$ H# G* G+ I7 h" S
- /**$ G' I8 G7 n. z7 E
- *Robot that stops if the buttons are presses before it completes its travel.0 F/ g& _# q( w) A) `* `6 w
- */
# F; y0 q% [, C$ k
3 M+ N1 G- f; d$ q- ^6 e! n- , _" H+ z" E! O: \9 U9 G
- public class Straight {0 l) H* E4 k6 k, ~
- DifferentialPilotpilot;
0 A8 A' z/ w9 z/ ?) I - doubleleftD = 4.3, rightD = 4.3;4 e+ h8 Q+ h! ]( M- Z% U; K
9 \3 n( D1 p; c7 \( _$ @4 h3 N- publicvoid adjust() {
1 g( u# n" W4 G: c) T7 B9 c - //wait for release/ U8 _$ s" i3 ]& C. p; t9 a
- while(Button.readButtons() > 0)* O3 S& T u2 k( G5 f$ {
- ;
" q+ N% x- X7 r- p( X - while(Button.readButtons() == 0) {, Y2 K5 _1 ^' R' p* {/ e# v$ |
- //input size by adjusting the wheels
: n. o1 t* s/ p) y2 U [ - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;. c" d8 Y f U6 x, k |( q
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
1 U9 ~' X9 J+ B5 z
' _, l' `1 O/ y7 O g4 V- //display the size input* J8 F' d: \$ ] U3 w% m3 I4 l, Z
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);5 s- e1 d6 g: O! M% B6 \4 U
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
0 t: q" q3 b1 g1 x% z5 H6 g) b - Delay.msDelay(100);
/ f; N# d! Q J - LCD.clear();
; b% i+ J' z5 s# C$ u - }
, W& A+ K$ z' t - ' f& {9 w% Z4 K7 h/ a
- }* g' I- [6 Z3 M; y \9 G4 {
5 p( g( }) o& H! ]6 \' w- publicvoid go() {
4 _5 [ f- r1 t. j" d: f - //准备起步
2 K: d+ ?/ L* `) l - //wait for release
$ _# N: E1 t) A3 f - while(Button.readButtons() > 0)
1 ]- }# _3 r+ C# K2 H, ^ - ;
4 F8 A3 S2 D* I& W. R - System.out.println("pressto go");
3 W/ |' @7 g, n3 k( G1 a, b - 4 q7 o5 ^2 A1 o* n
- Button.waitForAnyPress();
* X# U+ J( j7 t" |, @: a1 L6 v, ?# P - LCD.clear();
" ^: ~- q! A! V, u - % x. u* k% d5 @% q
- //初始化
4 |. [3 h R4 H# W6 v - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
K5 L% e- x& c* X - pilot.reset();
2 D+ `- a" I3 q6 b) G9 E
* `8 N- H% e, ]: ~% Q- Delay.msDelay(3000);
3 c) P/ ?4 V. |- z5 p1 b. c% z - , x6 B- O( Y4 P' M0 U8 y0 n4 D
- doublespeed = 10;
' ?6 C! J% I0 f8 E( A - doubledistance = 0;* J R. N: h- l0 k) M; R/ ?. D
- % k) T! q1 b2 }( B, y% ?
- //起步加速+ w! J' G$ P1 t. K5 {+ v
- pilot.travel(300,true);, o. d3 g/ w1 S
$ K8 I. {1 I% j% G. ~- while(distance < 20) {
0 g1 b) v( ?* } - distance= pilot.getMovement().getDistanceTraveled();3 _' Q6 N1 M) P7 b) C b9 A
- speed= distance * 5 + 10;! E1 b5 a$ M5 U* p, \9 O) T
- pilot.setRotateSpeed(speed);
n) B7 ?4 P# s4 K3 s ^2 B4 s - Delay.msDelay(100);
* v5 s3 ~9 ]. N5 Z$ g, N) | - }+ A* K, X, I% ]' {
- for(int i = 0; i < 10; i++) {
2 e+ R# l# Z" ]) _' V1 u y - speed+= 5;/ O: P8 ]7 U* X9 M4 C9 k) x
- pilot.setRotateSpeed(speed);
2 p! `. T4 x9 ^ - Delay.msDelay(200);
`2 h% `3 i0 O2 H& k7 n - }
* q2 t+ S0 N$ J- i4 @6 W0 ] - 0 C0 Q1 m' a; w" F7 D @
- //TODO 减速2 X5 b; z; q0 O
1 u( b& k8 m6 Y+ i, @- //停止机能
. J3 n' R! @9 P C - while(pilot.isMoving()) {
1 |: z% [& k% a; v' U' c - if(Button.readButtons() > 0)
. n+ ^; k! o" S2 H - pilot.stop();! U( ]8 A0 |8 J- {/ }; S( \
- }+ z: C- m. x: u# e: d3 y
- # {) w# N0 x9 w8 L( t
- System.out.println("" + pilot.getMovement().getDistanceTraveled());! D8 M& \- q; K, \+ y5 S7 q
- System.out.println(-Motor.A.getTachoCount());
5 R, z" t1 E0 k: M* c8 b - System.out.println(-Motor.B.getTachoCount());( k7 w, y5 t$ l7 m, ~ ~. I9 C+ n$ G
- Button.waitForAnyPress();$ c* h0 }7 q4 ^" `
- }
% H" H# ~9 b! b: q+ r4 I
5 X% m2 r) I. l0 z2 `# i- publicstatic void main(String[] args) {
+ `+ I. W# X) K9 @' V3 b7 k+ H" H - Straighttraveler = new Straight();0 T |3 `: C3 @! q
" G. A9 q% d x- traveler.adjust();
% J ]$ T" Z) Y- V* [" Y! L - traveler.go();
& C8 n+ P& Q) {( g - }2 Y/ b) P4 k0 _( t
- }
复制代码
8 _: V7 X* D! h* u |