本帖最后由 hello怪 于 2017-7-25 22:24 编辑 " q" w/ _* |% P# L
0 i/ L6 ~' [/ F7 C! @7 e, R1 E
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
! N; C. t9 S+ Y4 E2 \6 L5 p- d
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
2 q: S/ x8 a7 W/ Y场地
% h; F, }) i- |0 n7 B+ r 水平度和光滑度
在家里当然瓷砖的效果是最好的
2 h2 A* f" B: p+ l 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直, N! k+ v4 o/ _ k: N
' O8 N+ h/ c3 G. G, n. E; M( i
车子结构
3 K' s) t, U5 w, M8 C6 x 轮子间距
- K: Z* t' }1 t3 r1 n0 ] 轮子间距越大越好,稍微想一下便知5 a8 B# e$ N5 J$ n6 r7 |
轮子大小
2 ~4 S. U" A, u* c2 n- f 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
7 D, R l, S1 B4 a N/ ?2 L 随动轮的设计
- _8 H- g7 i% S2 W( e/ F 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
0 `& Y' I9 }5 x" a9 k) ~% j( t 重心位置
, n% h4 a4 ?( }8 x$ p# I+ Q) P 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
. ?# W8 Z/ E% ^" f0 j' e: l& p 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
+ N" g! F& j# S. Q+ ?$ }* Z 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
0 o* }. B) z/ d7 ]0 ? 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动: k: Z" B# W c& Q$ X
% H& I/ w8 R: b! K* @& N
控制程序
: q) s5 U0 g' ]5 ?/ Y( @+ P# B 运动过程控制4 {8 a8 R& o4 i3 G3 ~
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)" C% l# W2 [8 ^
/ v7 W3 w% O' N' K. b1 @调试与运行
" R% J: c- l& j$ f 轮子转速调整(车轮大小的设定)
1 ?! [% b) L' v2 j& S# g 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法3 ?+ k6 \; O% q
起始位置车子正方向和直线间的夹角
7 W1 H# f; }1 D! q+ z9 e 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ! D3 {; I$ Y: k. h/ T6 }
9 j! A$ B1 g! }. g
8 b8 u4 T5 G x1 d+ g, E: `
然后上源代码: - ' W# _. p7 q1 ?
- importlejos.robotics.navigation.DifferentialPilot;6 W' C+ J5 \0 ]) G5 _* B- ]
- import lejos.util.Delay;
! Z4 E' H4 g( R4 b& a* g - 6 B8 N3 k0 y+ `/ F- w2 B g
- /**; Z6 {7 X/ y* k/ \5 H7 x4 G
- *Robot that stops if the buttons are presses before it completes its travel.- z, [6 T& G, y6 ~$ g
- */' P: `1 n4 m1 T' k0 b
- ( c) V: _. a! k3 W
- 6 {( Y. a+ C( U# r$ p, {& b6 I( v
- public class Straight {
: @1 r+ i" S: X. u - DifferentialPilotpilot;
H+ P- \) Q2 w - doubleleftD = 4.3, rightD = 4.3;
5 ~2 d6 r: f, T* n9 v
: n6 C+ G9 n0 j) `7 A0 p2 F* p- publicvoid adjust() {/ J0 E8 i: }% r: m
- //wait for release
- t# f* N& D( j: P7 q - while(Button.readButtons() > 0)
; b' J( v7 l: i' e' s - ;
2 K0 }5 p9 x* j - while(Button.readButtons() == 0) { z$ u2 w3 x3 s% y& d
- //input size by adjusting the wheels
/ ^: L9 ~9 B" x" w7 x - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;* ^. {2 b- {4 \$ g1 q G
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值! `: z, m; n( N3 z+ m
: m$ o9 ~4 G% @0 [) ^6 ?- //display the size input' A" J6 b- h* n* g' c V
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);, w+ r! |' A8 c) l' R0 i
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
! i8 F* { C) q) V4 a: x - Delay.msDelay(100);
/ Y+ y! y0 y1 h$ W7 c; k; I0 q - LCD.clear();
4 V$ ]% h; P- T* v( q( K! X6 z - }8 P K% O9 O9 ]% y
% i" B3 k7 ~6 ?$ s- }2 ]2 g4 i; v2 Z8 g0 q$ y- x; U
- - U6 ~$ f0 G2 E* w" o! E
- publicvoid go() {5 y- E" A9 ~3 `$ N# n- R4 j- I
- //准备起步" }8 h# a, V* u* C
- //wait for release
6 z" E7 X* k2 E# |( z - while(Button.readButtons() > 0)* t4 k f* T' c0 c5 X# T+ W" l8 D# A% p
- ;
& S) ?% V' w. Y- ?9 ?% p- J9 J) P4 v - System.out.println("pressto go");
) p) e% X; s! p9 B% R - 3 c+ t! T, m& j# X
- Button.waitForAnyPress();. k; N' F' Z8 g1 H2 W& o0 h
- LCD.clear();" j6 t( P, C, ?/ |* }7 C4 W; y) u
- / d3 p9 O8 f }5 W* H/ h" y+ ^
- //初始化
7 h2 z4 {4 N# D$ P o& s( k. g- c, x - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);, g8 ]- A7 w1 d N* V
- pilot.reset();
2 A5 a4 o. C6 R( _. O' d: L" L - # I" d9 _3 E) ?1 C" h3 g* S
- Delay.msDelay(3000);, T$ E' Z m1 |. ~
/ G" w# U; W8 X a% k% Q# a k- doublespeed = 10;" v9 E {8 j4 L- N; }( l% m
- doubledistance = 0;
6 t, j8 e4 X3 e/ k; j
N+ G$ ~9 X3 q0 t. B) N3 u- //起步加速
$ ]4 ~3 ~: k, t) B( t' j3 l - pilot.travel(300,true);4 W h, l7 Y: F& s
2 ?3 M+ O' S' ?" {- while(distance < 20) {+ h0 p( T* w f% ~( S
- distance= pilot.getMovement().getDistanceTraveled();6 k0 v$ h* K0 \, _# a8 P
- speed= distance * 5 + 10;
; e, ?! x/ L" `6 z- U% ] - pilot.setRotateSpeed(speed);/ C. C5 `) U; _; u9 ^
- Delay.msDelay(100);
% s, K. b8 _; E6 Q7 Q - }0 r {9 g" o3 F9 m' L
- for(int i = 0; i < 10; i++) {
: v$ t6 R( m- f, u$ I+ n; m2 B - speed+= 5;
+ f% d" K2 M7 S( x1 N - pilot.setRotateSpeed(speed);
; x' r; N7 P7 {! p+ b& I% w - Delay.msDelay(200);
" f. W: _% x; o' q( U; l- `8 v - }
& K, D6 ]! s0 K; C1 q0 O - 5 G, r) [; d' h( w3 |7 F
- //TODO 减速
! }1 d1 i: ? V! D3 u
& r* U* c" v' r. Y- //停止机能4 ^: A0 ?5 R6 Q {4 ?' \
- while(pilot.isMoving()) { j9 | ?! L. V% b6 }3 M
- if(Button.readButtons() > 0)+ y! t$ {7 P/ u/ y+ [5 _6 R7 ?6 U2 w1 `
- pilot.stop();
% n& ~5 K: M" E0 [& | - }) r% b% `+ Q% f1 Z* E; l
- 5 G# q! q5 b# ?2 D" }6 @& i- `
- System.out.println("" + pilot.getMovement().getDistanceTraveled());
& J( V. z2 K& {0 k+ i; `$ v - System.out.println(-Motor.A.getTachoCount());. Z/ g4 R4 N* {) S" O
- System.out.println(-Motor.B.getTachoCount());
& U* H2 X1 x$ k" y, \ - Button.waitForAnyPress();
/ y/ t% ^$ t( _ Y/ J8 J$ {* r - }+ K7 s, ~2 r/ ~( I% l
: \% v# a7 e; J3 w& C3 @- publicstatic void main(String[] args) {9 O9 P# }3 D0 X% Z- j& @
- Straighttraveler = new Straight();# H! P* K9 J! X" q5 w7 a6 {1 D0 b
$ W8 p& p3 ]7 Y# n7 w- P' ?- traveler.adjust();
! H J( f }0 F! g - traveler.go();
% J. a' ]0 J: p# c - }
3 ]& V& u. k, e+ u2 z" D - }
复制代码
5 Z: P' S+ U1 K2 I$ L4 p& A |