本帖最后由 hello怪 于 2017-7-25 22:24 编辑
$ {6 o7 E1 F( B7 i. D/ g
% c8 ~5 M% A' H(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html + O5 U6 R k" ~- A
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
+ \( N1 d+ f2 D* E! i/ `% ~场地
; c, {( W- s) `: | 水平度和光滑度
在家里当然瓷砖的效果是最好的
' Q3 Z* a5 s2 B- R0 e. [1 A 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
1 D5 I7 e- U8 L. d" j- d, d% e+ I; m: P' l4 a7 x. E8 i$ t# o
车子结构
( N8 D: ]1 p& ^ x( {" g 轮子间距
' {# F: A# Z- v* K 轮子间距越大越好,稍微想一下便知, W2 h% O. K N& S+ ?7 ?; z
轮子大小
5 O7 m1 Y4 l* [8 X2 t' M 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)" l3 I% j A% c1 [) m8 y
随动轮的设计
( ^5 ^$ ^* p D0 w9 ?: ^ 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响" X- p3 }# D9 y
重心位置
( w, e7 J- A2 } 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
( W7 m$ C; v! y& j, K' q 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
; H+ U5 K" l. }" e0 x# }+ D 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
1 T! d& F* r: ?( \6 M 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动- x' C5 t; l" f% ^
7 w: ~/ s, C5 U% @8 v$ r
控制程序! A/ T0 j# H5 D3 K
运动过程控制* O5 \9 ]0 r* ^; {( M
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
1 |' N8 Y6 r3 E8 O. L/ @& J; F; c
+ Q, C- x" ^& s: `' R# h调试与运行
( ~% _6 v. \$ F5 a5 V w; H- g 轮子转速调整(车轮大小的设定)
) {1 X. R7 Q+ W+ E( _ 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
% j) z5 o! w. |8 {; K 起始位置车子正方向和直线间的夹角
! w* x% G7 J, g/ N. S 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 * q4 N) _) Y+ [, X
4 ~2 k( q+ W) y) X
4 z& b8 i" [, M8 ~* f( M; E: e7 b 然后上源代码:
, d' A9 S0 X" A3 I* R- importlejos.robotics.navigation.DifferentialPilot;
+ ~; ~* I( u- F v' W- c" U - import lejos.util.Delay; o% L6 e* n( e9 ^
- ! @2 x( l p5 L& g
- /**0 x( ~ o+ {; x' h8 W
- *Robot that stops if the buttons are presses before it completes its travel.
' M) B6 O. q: b0 c! ^8 [* A, C - */
^2 h* c& U& ~+ e/ f6 E - 0 u0 L) ~) v& J5 f; \
- % b4 P) c( q6 J- \" Y
- public class Straight {
0 t8 G1 L6 w* i' v* r - DifferentialPilotpilot;
+ ^8 F3 ]( x! f! H$ V8 K" w& Z - doubleleftD = 4.3, rightD = 4.3;# H8 \: k. }* [6 o: O" N3 X0 d9 \* V
- " G+ ^# p S4 p* W3 u3 B
- publicvoid adjust() {' [* a6 j& S8 `5 n6 B, | J& Z
- //wait for release! ?6 H3 V+ I0 h( s, B* n
- while(Button.readButtons() > 0)
+ E$ m# }5 \& u" y4 q7 @6 G - ;$ L6 H* c" p) a" g
- while(Button.readButtons() == 0) {
* I& w$ F+ [" E+ K6 l+ ?$ T: d* l - //input size by adjusting the wheels$ E- ] N }3 e
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;4 I) Y: V# L+ Z; y
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值. o+ j# ]2 s1 ?0 r: G; [/ |
- 2 Z( b- ^2 n2 K& A/ e) Q# U
- //display the size input
3 _6 @" i- A- \% ?$ r, R1 Y - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);& O, Q0 R- H$ r
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
0 G/ F) K0 E, c2 s+ d+ H, u. f8 L - Delay.msDelay(100);) A. A0 B6 f2 m4 W7 Q/ B* G& B6 P
- LCD.clear();
3 G1 ?& O! g2 j6 ?' s7 T$ _ - }
" w) R# D& D/ U j - 4 B6 U& R3 G+ K# Y" I
- }$ L5 J* B c$ [. k" C
8 i" A& V# y( H' N* D- publicvoid go() {
7 S X8 I0 T6 U7 S8 ^* T7 C$ r, G; V - //准备起步. N- F$ x0 B8 U. {5 @
- //wait for release
+ ]; _6 }% R7 i' w' \( I- F - while(Button.readButtons() > 0)+ x4 P x- o* x; f$ d8 B7 y8 x
- ;+ l: O( a' q1 l, Y. H; b5 |; Q* V
- System.out.println("pressto go"); s3 k) e3 P [5 Z$ w
- 2 c; [5 |4 E% e6 @. c4 W
- Button.waitForAnyPress();% r: }4 l7 R7 i1 ?
- LCD.clear();
* p* B2 s$ l' R. S. P, z) u: l - : m6 ^: ~+ g8 Y1 |& ~: }& i
- //初始化1 g7 x* K p9 Y s7 K# h& H
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
8 g2 n" [% I! Z5 B5 @' R, j% d - pilot.reset();" o* G# U) Q% F, j
- % j! i' [7 K3 e9 W
- Delay.msDelay(3000);" n( W( K7 C4 f
/ G9 v& G, C# t7 Z* O- doublespeed = 10;
: c' n9 n( v& {' p1 V5 K- p - doubledistance = 0;3 r; ~4 S" R9 N8 n7 [) m
- : m8 c) v0 x! c8 \$ X- J5 e
- //起步加速3 _( h6 v; q- d9 ^3 @( t' o5 k4 b7 m7 m, g
- pilot.travel(300,true);
5 W* o7 F; V v- H" b - 4 ^( ^8 Q; ]& D4 }4 A4 K
- while(distance < 20) {
4 H, u1 X# T" e3 i& [5 x - distance= pilot.getMovement().getDistanceTraveled();; `( V0 P& F. y5 i
- speed= distance * 5 + 10;
3 q2 \$ N" Z/ p - pilot.setRotateSpeed(speed);
4 w4 h, |/ ?1 C0 o, ~" o7 L - Delay.msDelay(100);0 P5 u( ~; x0 n- Q% g
- }
) b+ \ U9 [ X) W; I - for(int i = 0; i < 10; i++) {
1 b f$ U( B& `) O4 Z3 C - speed+= 5;; a0 h9 q: g' W* ?, w
- pilot.setRotateSpeed(speed);
1 x- |5 F1 h$ ]3 D, Y$ d: _$ s - Delay.msDelay(200);
( ?. ~1 c- c% k( a) V - }
. g0 s- j# P8 x0 O! T - 0 I9 N3 i( b$ m
- //TODO 减速
' F% f0 B5 T) }$ Y9 P' k - 8 y- k; h3 a c2 o! v
- //停止机能5 o9 ^! e9 V& K8 ^$ G
- while(pilot.isMoving()) {
' t- Y1 T% \5 s) E - if(Button.readButtons() > 0)6 q! j' @5 v0 b& C3 M" X
- pilot.stop();' F( `7 w( O; T4 i
- }$ P* Z4 v) x! Q* o. ], e
! {' N2 G/ Y* H- System.out.println("" + pilot.getMovement().getDistanceTraveled());5 S* j8 _1 O; q3 t7 v1 c# G
- System.out.println(-Motor.A.getTachoCount());
7 F: x& Y) t& M2 Q- a9 w: V. M% r - System.out.println(-Motor.B.getTachoCount());( z5 v8 R, }# r' X
- Button.waitForAnyPress();& E* r/ E! q2 }* u& i( u
- }4 `' `' l% D4 D8 A. x$ Z
6 K' y* d. e1 g1 s0 {- publicstatic void main(String[] args) {
4 I1 X2 C& a# A2 a P- S2 h. W1 J - Straighttraveler = new Straight();! L8 D1 j' J. n* V3 z; _' z
: R! g, l6 q; c$ K) f- traveler.adjust();% e* |$ Z7 o( w
- traveler.go();) B1 W2 D; E6 H+ O& P3 T) O
- }6 u# [. O- T& Y3 Y, |5 o# G
- }
复制代码 - M) }* X. k4 a' m4 K. E" {
|