本帖最后由 hello怪 于 2017-7-25 22:24 编辑
/ B0 B# \/ i0 u9 l
* j: C1 T5 g9 z' S8 ?9 n(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
( t; h( u# _# C( z
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 0 E U3 \8 p( F4 D8 Q
场地
6 j/ c9 S9 E* B& b2 ]1 u4 ~ 水平度和光滑度 在家里当然瓷砖的效果是最好的0 P6 t3 l) Y, @; l1 W0 {, k1 h
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
+ [+ Q$ ^2 }$ p+ _* L5 u0 h& B6 L+ f3 S: Y$ ?
车子结构1 `1 q7 R8 ^) P9 E0 D
轮子间距4 V6 q' w% ]4 M# ]! G. O
轮子间距越大越好,稍微想一下便知
2 @) ~4 k4 B) ~+ F8 i% u& Z5 w& h 轮子大小
/ ~, m1 M& q5 s1 l- n, o 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)% q0 U( k! U2 A* h
随动轮的设计+ j0 B& R) Z% P3 i! y' q
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响" `: A4 v4 s5 p9 y1 K$ e. O
重心位置
* t0 U; k6 Z P" r$ p7 K 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小7 U( y) G+ B8 e% \ J. ?; I$ d
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
2 R! W. Y6 R. _% C% |; m- V 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)1 P/ i5 l9 ~7 B1 N
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动* G% i' p1 e+ |
) l6 B9 o# J; Y. n2 l# D6 `6 H# \
控制程序0 l4 T* ?8 N* o
运动过程控制) `1 F3 B+ \5 g" t! Z
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
& U3 |" r' v+ j* [; U0 g- C* x
4 x' b4 `' p. F: j% q调试与运行
" K9 S4 W: r( H H 轮子转速调整(车轮大小的设定)
# o3 f8 p9 Z9 Z$ Z$ K 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
5 \" p2 ~& _/ E/ X+ E 起始位置车子正方向和直线间的夹角
( d& }6 F# D! N6 L' k 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
/ @% v2 S1 v9 s' T B% q
( I& ?$ H- U) S
3 _ u5 l& q2 Q" d/ ] 然后上源代码: - 6 G8 K4 Z1 g5 M7 Z' o
- importlejos.robotics.navigation.DifferentialPilot;
" l) O$ T: ]( E5 C - import lejos.util.Delay;
( A, u6 r" T4 i8 ^2 Q6 k# D
- o9 ]' Y9 B- U3 u. }4 [" ~- /**
9 y" z# ?6 D0 _2 }1 h A - *Robot that stops if the buttons are presses before it completes its travel.
9 V- E0 {$ A5 V+ l1 f - */
# ]" F5 P% z# v$ n/ u - 9 U P) a4 u) t2 Z+ m& M3 t( r7 O
6 E7 m0 {- E' X8 p1 u5 y- public class Straight {. d5 O/ N+ r1 I2 G1 @/ i+ |
- DifferentialPilotpilot;
$ H% r8 n) J4 t5 w6 Q0 a - doubleleftD = 4.3, rightD = 4.3;$ E+ C k. j; U
/ Z7 [: v' c/ P8 j$ X# U( u- publicvoid adjust() {% M- W- [! K9 {* M6 g1 n. ?( o
- //wait for release6 ` B7 \9 g$ `& O/ n; U. {
- while(Button.readButtons() > 0)
) u8 B8 Q& ~: A - ;8 |' L+ I! ?8 i$ ]& q
- while(Button.readButtons() == 0) {+ N* _1 p, C) O: p
- //input size by adjusting the wheels
4 F0 \0 z1 D5 t* Z* ~ _; h - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
: R H% g, H& ]( Q - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值5 \% u6 ^; I, ?9 e4 i
- " P! O4 [6 i4 c
- //display the size input
! T2 b% r) p A2 h - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
: Z% R1 u3 M% t0 b; b! B0 j; r! G# r - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
1 O! T2 v2 {# `) y( W) | - Delay.msDelay(100);% f8 C, \- ?, P
- LCD.clear();
7 r: ?7 {2 r; a( }0 r - }
! y# O6 F1 p. B% J - 9 d; E, P& h3 y/ m" E. N- q
- }
& t, Z+ r+ {0 `0 }
1 {2 T$ \) g/ a, l7 h9 I- publicvoid go() {
* W) p6 C0 |5 R$ y3 E* @* L - //准备起步
7 c" u, @# ?' [4 @; _ - //wait for release
% @2 L/ u) u6 a3 |1 U - while(Button.readButtons() > 0)5 i2 C! b# Z$ o
- ;
% }& {$ ~) {3 f - System.out.println("pressto go");7 D1 o! ?) P4 j# \% B& o
- % O) \5 p+ X5 c# ]/ y
- Button.waitForAnyPress();2 P! h$ g z, t( L
- LCD.clear();
" C, i5 o( u7 v2 r" R8 ^8 ? - , \" s# d# C# `7 L6 Q& B+ T
- //初始化9 O* G! ]: g: j/ C
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
8 U9 t* P; T& o/ A& ] - pilot.reset();
% @+ Q* G# n. W9 M
+ P6 q( o- O: _& a$ t2 H: }- Delay.msDelay(3000);2 i% E* D2 d7 {: _# B
- 5 t) }0 e. W* n: L# S. c; G
- doublespeed = 10;( V9 C x4 {( {' R( Z7 ^
- doubledistance = 0;$ r: U! D3 H1 w1 h
2 c7 x' ?; G6 U8 S* L- //起步加速* s- T8 H" c9 C/ o
- pilot.travel(300,true);* t- ?+ U% Y1 p& O
- 5 L C4 C7 k: r6 H
- while(distance < 20) {$ O! w1 e* K& g9 h
- distance= pilot.getMovement().getDistanceTraveled();% R6 Z8 s6 P W$ z" A4 o- J
- speed= distance * 5 + 10;
6 Q% ~4 d0 D o' [ [* p - pilot.setRotateSpeed(speed);" p( @2 Z6 K1 v) D, R
- Delay.msDelay(100);+ A: L I6 \$ k. l. ^( W1 }1 C
- }
- s1 q* }( q4 x- j - for(int i = 0; i < 10; i++) {4 V- }4 r" D0 G9 T
- speed+= 5;2 x. ?" t; Q9 b) }
- pilot.setRotateSpeed(speed);
9 H4 C3 B' s! D# p# }2 ?& ? - Delay.msDelay(200);' N7 s1 F( N$ Y# d. Y- t6 U
- }2 D+ Z; n! Z' M$ ]7 U. ]+ i
- / |% l0 |) H( O$ q- g$ }
- //TODO 减速+ q+ N3 ~5 _9 a7 R0 i) f
/ d) a( |7 ?2 I4 B, A5 _5 ~- //停止机能/ G7 n$ v' L7 A6 g4 ?. K+ j1 X
- while(pilot.isMoving()) {( }$ x& E3 M5 w
- if(Button.readButtons() > 0): J+ R: w$ b1 ^' R( s! ^
- pilot.stop();
$ I/ ^! M+ a y# Y* x% w" I - }
. w S, k# O, L: `4 l- Q, X2 K
! M! r: o# o! ^2 m' H- System.out.println("" + pilot.getMovement().getDistanceTraveled());' d; y2 w$ E7 R
- System.out.println(-Motor.A.getTachoCount());
9 v( W" ^4 o& | - System.out.println(-Motor.B.getTachoCount());
$ q, Q9 ?) r! u) y: K - Button.waitForAnyPress();& v* P2 ~7 d' h3 f
- }$ r) t* x, Z4 G1 G8 Q& m+ M
6 x6 {8 A6 @- o3 j6 E( _- publicstatic void main(String[] args) {3 W/ f' q: o9 @, w) A5 t
- Straighttraveler = new Straight();
/ ?/ E- }. X* l5 B# Q. T8 V3 I3 ~ - m7 q# q" D3 p, R. _
- traveler.adjust();
1 M* {! j3 D3 F- S+ j' w - traveler.go();' d3 }$ b6 X, z5 B" d
- }4 f( K/ V; R+ ^- ?
- }
复制代码
: F, C7 U7 M& I0 i |