本帖最后由 hello怪 于 2017-7-25 22:24 编辑 : O7 g3 S: ]! C- I7 C
: p( t# }) {8 X$ u6 B
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html : T# z c+ Q6 |/ d2 r
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 6 x }6 I' o. j
场地- V6 O- y/ B3 O& r. {: c
水平度和光滑度 在家里当然瓷砖的效果是最好的
7 p0 y6 w; U+ o5 B/ k 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
8 |/ A% p; C1 a& L% ~$ H. v0 ^
! W4 j$ t! \& @车子结构$ L B, H% O* ^7 u
轮子间距' V, H, J+ z+ Q( ^) s$ O; Y
轮子间距越大越好,稍微想一下便知
& {- V# H E: q9 G& V( g& C1 j; M/ b 轮子大小7 y" _+ s( V$ X+ _ K. F* e
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
* I: l' y# h" @8 ~9 Z# ~+ E" c 随动轮的设计
N: `) P- S; d! ^+ Q$ F6 Q! { 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响0 o5 e4 W) a2 Q+ k
重心位置
0 c* ^3 q0 w* A: D 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
7 @% u" a7 X" x' N7 D2 g1 { 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
) e$ ?7 M' [- ?( [& T 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# T0 r; F5 C" R
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动/ l& v8 x0 ^9 E4 I; R' q
: F7 p& R& I" J+ A& N7 ^, P/ R3 p
控制程序
4 v% o- {) _; R- N; a; | 运动过程控制; A. B) }3 [: `1 ]
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
1 e+ w- }4 G. L( |" g/ s8 b: ?% j; i, `6 L) }/ p! [, i0 x( d7 z) {
调试与运行
) _7 E. E% D+ ~# | {1 V. G 轮子转速调整(车轮大小的设定)
& `3 u6 G3 C" c! F. g* M 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法' ?- w/ j( K: O0 C$ g2 V9 f7 ]
起始位置车子正方向和直线间的夹角
7 I; i2 L' _) v 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
$ _! e; B/ _5 s6 W: S+ g; a# o0 J* X5 F" [; K' O/ r3 n: I. J; x# q# b
7 l/ `' k6 k* }, F 然后上源代码:
# ^: g/ ?% {" k4 S! F' L2 b- importlejos.robotics.navigation.DifferentialPilot;) f7 _0 d) K. f8 g2 H6 d
- import lejos.util.Delay;
& J% d/ N- ?4 ` m0 R% j9 U+ ] - : v1 m7 U8 I( P+ u7 ~. v# @; W# w
- /**
9 F* `9 R& q/ N/ N% I( e) D0 ^" X - *Robot that stops if the buttons are presses before it completes its travel.7 H* U! `8 h5 n) J/ U% \- n# c, ^! T
- */
. n0 Y+ M# r1 U6 c$ r - " `: d `* E: R1 h2 w
) N8 i+ V1 g6 R; U, Q3 {8 J; `9 R- public class Straight {
- S5 S8 _0 j& p. r/ R" ~1 h2 f - DifferentialPilotpilot;
1 w6 F1 u N% f0 H - doubleleftD = 4.3, rightD = 4.3;
2 g- K$ s1 d5 L* ]
, b d& y, ~5 T9 C1 `- publicvoid adjust() {
; o1 R1 s Z# P: ~ - //wait for release/ i" P2 m5 R, Z6 k
- while(Button.readButtons() > 0)) x4 |; x' ?6 Q: o$ B0 D
- ;
2 E/ B$ ^9 R- w1 t4 x! m$ J - while(Button.readButtons() == 0) {) d' s6 u8 p7 U f8 Q. [/ f
- //input size by adjusting the wheels1 t8 Q, U& @$ @
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;5 X/ E, F/ e3 v3 \4 }; f
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值4 N g8 P& y0 G: ~
- 7 A; W1 T7 S( Y/ s+ [
- //display the size input; R8 i5 ]. b6 }9 O$ V6 T
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
( X# V! u: `/ | @ - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);3 [+ m' r+ g$ n
- Delay.msDelay(100);& s5 Z0 s6 A- l0 o& s8 q5 Y
- LCD.clear();
- l# `8 d! A+ b4 } - }! A. U4 D6 H4 b
- ! O6 ]& z' R+ d& c$ e2 Q. d) H/ W7 ^, X
- }& T3 p1 j2 h# u3 w) b! j" w# s
+ }* A7 \5 p4 ]4 _# T; V$ K' N- publicvoid go() {" l: R/ f( W2 O( r% H; o3 F
- //准备起步
8 Q c+ o/ N5 q& i* m4 E - //wait for release
& x: @% h3 R/ n, k - while(Button.readButtons() > 0)8 H9 M0 W9 y4 c' v1 j# {
- ;
; B4 T |* g/ i - System.out.println("pressto go");
- Q- p6 j/ _2 x
3 [4 V8 d; z. O( H1 Q" ?- Button.waitForAnyPress();
& W4 R9 l n$ H/ f8 B) X3 M& u* {. U - LCD.clear();+ Y" o5 k" [5 ?0 t3 H3 ~
- ! j) \) _6 G. s0 V3 ?9 e C( z
- //初始化" U" d5 U. x2 F- c2 p# z& g
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
. T2 m7 w9 z K - pilot.reset();
/ E1 f2 @8 [0 C
5 X q" I; D; O. K% l# B- Delay.msDelay(3000);
, Q, ~( E* O* ^$ w( Y4 D
% p8 o% T" n3 v/ Z% K* {, N- doublespeed = 10;! F( t% ]7 b( \9 z6 ~4 i( }
- doubledistance = 0;
2 _; ~' @: ?; O, o$ F - X5 O3 o2 }6 l% ]
- //起步加速
# y D/ y( H( H4 _ - pilot.travel(300,true);
4 ~, H: h( Y9 s, n& p4 f5 @ - , M2 G, L) j9 Z7 h
- while(distance < 20) {
4 F) v c& [- E+ }8 h7 G - distance= pilot.getMovement().getDistanceTraveled();7 v% c* S" @- z V
- speed= distance * 5 + 10;# W. a+ x8 V( ^1 N2 ~
- pilot.setRotateSpeed(speed);
8 C) E" c8 I5 p9 o5 n0 _1 b- }2 z0 A - Delay.msDelay(100);
, ]) j$ j# g! y2 S3 F! s7 t - }5 O; O3 V5 x* f+ c- ~% T
- for(int i = 0; i < 10; i++) {+ `" T, K4 n; ]. [
- speed+= 5;6 x0 \( e, ]) c
- pilot.setRotateSpeed(speed);2 w+ s l5 d8 O+ i
- Delay.msDelay(200);
' b. n7 t. [$ P3 }3 I: ^/ R - }
/ B5 \ m$ ^9 E
1 {7 w/ W9 y' T- ^0 L; H1 l, G- //TODO 减速8 \5 }( C" Y& N; d0 \! f$ t) M
- 9 O; e% h C; C# D
- //停止机能
5 T8 j9 u: S9 z7 D) o - while(pilot.isMoving()) {9 n s4 V, \) C5 U' @; X
- if(Button.readButtons() > 0)) _. Y2 l& ^/ \& v$ t0 Q
- pilot.stop();
' l% g6 j; j; Z, o& q u* e - }
" g0 [0 T2 f O3 w3 M i: I - ' d4 B* K# o0 N% p4 u
- System.out.println("" + pilot.getMovement().getDistanceTraveled());
$ t0 S `) D0 A4 H1 r2 g - System.out.println(-Motor.A.getTachoCount());1 ?- {. i7 K( n( N
- System.out.println(-Motor.B.getTachoCount());
0 U* y$ i5 y' D4 p9 s9 m - Button.waitForAnyPress();
w4 {5 L: W$ S, ^. N7 o - }
! k9 E8 G* z( ?* { - ; p0 E) p0 n* B/ C2 U
- publicstatic void main(String[] args) {' O4 `/ o3 h9 \4 q* ~
- Straighttraveler = new Straight();
$ [7 r: ~8 g3 I- j0 t! R' [
( U. d3 c( }2 @- B- K. w% b7 p! e. ^- traveler.adjust();; m" u! Y2 r+ l, a
- traveler.go();
( G, s. i3 P( ~- ? - }$ L: `3 F, O5 [) w8 f
- }
复制代码 % E" t5 x* J; ?! s1 J1 b) W! g' j, l
|