本帖最后由 hello怪 于 2017-7-25 22:24 编辑
. y! g% T( L2 i+ j4 F. u
" m9 Y7 r% k% f* P; s z(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
4 T5 O8 h h- Y/ I) |" S5 N# z3 s
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
& w v' s% i) v场地
1 Y2 u; ]' g' S& U, x 水平度和光滑度
在家里当然瓷砖的效果是最好的
Z# s: ^) u& Y; A# W3 B$ h 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直# h, g7 f' }) B, P C
8 n) @; D c. P+ f" S$ S车子结构/ M! J# ^# w. \/ b/ F6 i3 h
轮子间距2 r* E G. x% W4 m" d/ L t9 E c5 Z6 ]
轮子间距越大越好,稍微想一下便知( ]# }' j, c: r0 Q
轮子大小 e! [8 ~/ q2 `7 ?
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)0 q' X9 X* l3 r9 m
随动轮的设计
9 X, ]2 o. C2 n3 I3 K& N& a/ Y8 D 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
4 Y W5 L+ Y2 l l B0 @% D 重心位置
& {! q J# \6 O. H* ? 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
U9 G9 {7 h+ R# g$ V 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大* v8 o! J- D! d
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
& S U. z" w- ~& p5 g 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
7 t9 ~; S0 G+ G% T1 I2 ^8 g1 D' N3 p; Y+ Q1 p
控制程序7 f5 Z% J* B f, f3 `% N
运动过程控制9 G) `( w* N7 B
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)3 t9 U2 U6 @9 o1 K
9 w( t6 L _ Q" Q0 O, U调试与运行/ f# p! e: `* p8 ^8 u- d
轮子转速调整(车轮大小的设定)
9 D9 s/ e8 D4 G1 ^+ j5 C 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
# ^# I% l1 v' M; P' ^& U2 g 起始位置车子正方向和直线间的夹角6 J$ t1 @5 o P/ P' D3 [6 R" P
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 * {6 |9 {( { e6 D3 R" Z; q y
9 t4 U0 X+ {* x& l G( R6 d: g
+ @* a6 ?' J" Q; t 然后上源代码:
$ A9 r0 n, \9 F# H- importlejos.robotics.navigation.DifferentialPilot;
0 l! U W# N j) B# v: a5 O( T - import lejos.util.Delay;
: Y4 G- q+ r8 ^/ M
& }1 P* Y9 D! Z* ~0 \! L" {; G- /**- J4 [5 d3 j9 e; e4 T* A
- *Robot that stops if the buttons are presses before it completes its travel.
3 K1 v. u0 z6 x - */
, ~2 P( H0 y3 }4 ~/ M% i- y/ @ - 8 H) b, ^4 x4 W- s
# V! n: M5 `& K- public class Straight {
1 s( |0 G y6 l; ], m' f: @1 W - DifferentialPilotpilot;" q3 s+ k- K+ X, F
- doubleleftD = 4.3, rightD = 4.3;
3 H8 h* y/ E- a! U - 8 n. O5 \6 B1 w+ N2 k+ q9 t
- publicvoid adjust() {2 i' E& ^1 Z' e: d" `3 q G! `
- //wait for release
1 d1 M7 q, f! X5 F+ A$ V% `1 j - while(Button.readButtons() > 0)2 M* V+ \! y) r% c+ ~7 c
- ;
' N6 ^! W# B* p - while(Button.readButtons() == 0) {
; Q# A2 | B9 A( r3 O0 x* K( F - //input size by adjusting the wheels! ^. X3 t+ P( ]) X( ~
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
/ e- k$ |, z- s0 s; y - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
: y1 D# q" v# H h - 9 y! w5 ^4 Z& J2 p
- //display the size input
2 u/ y+ a% i" a c2 U - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
! b2 D0 ?/ F5 i7 o( g - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
2 m @2 V; d1 S - Delay.msDelay(100);3 ]4 g. m# H6 j q
- LCD.clear();
/ Z8 ^' \: B3 H3 D3 t0 I - }
. }) @8 C1 k7 m' j, a. ~( e [# x - 6 n) O0 n! T# a5 E7 J# K. s
- }+ a; J, p8 @8 g" X! z
+ Z$ t% R. W5 G- publicvoid go() {* T, n5 D- s% _( T* r8 T% ?. Q
- //准备起步
% S" q$ x( ~: R% Q - //wait for release
) I& U, i0 B, N6 p: H) W7 w) ? - while(Button.readButtons() > 0)
5 `) ~" n r6 F( K: S0 K - ;9 Z% N! Z" @7 m0 { T( B
- System.out.println("pressto go");
' p7 E Y6 r& u0 @# Z2 F - 5 d- b/ T( J" q. }4 m# }
- Button.waitForAnyPress();% @# ?( i* s) ^" [: x2 @- o
- LCD.clear();
. ]5 M1 t8 D; H/ N. R - 5 K8 v6 d# e9 l7 E8 v
- //初始化4 \! h0 m8 P8 D+ L3 K
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);1 R0 v! K- V- |* \
- pilot.reset();% X0 |8 Q4 h2 n4 u0 V! U. ]+ f
7 I0 b) f: y3 n ^- Delay.msDelay(3000);8 Z: N' w7 ]2 o. [2 ~) I4 U
; y9 [$ F. I" l1 H* q6 H0 p- doublespeed = 10;
& [# S) x4 ~2 z1 o - doubledistance = 0;6 i% c% M) s3 h4 Z7 o
- / n$ s* ?1 t5 \& n" @0 t0 h
- //起步加速4 N0 S9 Y" ?1 h
- pilot.travel(300,true);4 s0 y4 ]1 ]/ z0 k: A5 A* {
- 2 O9 l3 ] _3 t" `
- while(distance < 20) {! \1 P; l. S5 L
- distance= pilot.getMovement().getDistanceTraveled();: q2 P( }9 w9 d' m$ I& @
- speed= distance * 5 + 10;' K5 x& V7 d0 U$ [
- pilot.setRotateSpeed(speed);: l! V2 |. f5 V9 c+ t
- Delay.msDelay(100);
k6 y" C: W& I* g# o- { - }
( a$ @4 ^% `" E( M! G: q - for(int i = 0; i < 10; i++) {
1 y6 R+ ~. ?: I% s - speed+= 5;9 ~& U+ c' @; C0 @* N! e
- pilot.setRotateSpeed(speed);
3 H+ K1 X k8 l5 }, d - Delay.msDelay(200);
: n% m/ N1 W. b. j - }
9 X, N! \- }, N0 x
7 n0 S; @3 @! |- //TODO 减速' T: C* u" p% _( y- u% a8 C
' }2 ^/ N& \: _: M* P# r- //停止机能
& X5 z% o' r6 z& _: }/ U: a - while(pilot.isMoving()) {! O( [3 q4 z3 A. Z
- if(Button.readButtons() > 0)* p* }, h/ ] Y8 S, W( b
- pilot.stop();( ~7 |' U' H9 ~& S" b) F! L
- }
6 X- a' { U- y- D. J8 l9 s
6 M' {6 f1 G3 v4 \ o0 a/ Z' Z- System.out.println("" + pilot.getMovement().getDistanceTraveled());, g2 t; q. M# o; W% o
- System.out.println(-Motor.A.getTachoCount());
( x9 X) @$ h2 p+ O5 X! J - System.out.println(-Motor.B.getTachoCount());3 V" w/ x5 g( Z% Y5 j9 `
- Button.waitForAnyPress();
+ g* I, i) A) \- [+ V' o! E - }; L. e u1 S. P' Z" E! J
# i8 T) N4 R. M/ O) Z- publicstatic void main(String[] args) {$ {/ D9 R7 Z% g5 g% M
- Straighttraveler = new Straight();2 h* j0 l4 G) T
- : ?6 `: t% H5 Z3 f
- traveler.adjust();
) I5 {% z. V) X6 j4 S# u - traveler.go();
( a1 k4 p$ s' j - }' `+ o7 y- K8 K8 ?% p/ f0 E
- }
复制代码 : v5 [1 I" w1 g9 N9 E9 V
|