本帖最后由 hello怪 于 2017-7-25 22:24 编辑 ' X3 j8 C; D9 Y6 e' n5 A* f
8 ]* w0 ^9 t7 k* g' e) U2 [
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
0 M/ m/ Q/ Z. q. ]) @7 g$ w
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
7 u6 v9 [. H; g场地# }4 B, d9 ^0 }, @" Y
水平度和光滑度
在家里当然瓷砖的效果是最好的
/ Q- n: h6 I: a/ t ] }* a 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直% T3 ?, u1 a, Z- C) A. T2 K! p
% c# u5 k, M3 e. y. n
车子结构( `! Z: x( O8 q( @, a
轮子间距
$ m9 j3 L2 `$ p 轮子间距越大越好,稍微想一下便知3 Z; }2 }6 G" O. }0 T
轮子大小
, g! `8 T) v" W8 u' A9 k 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
8 Q+ F8 a% g9 `, j 随动轮的设计
0 m6 |3 L% m+ C* g1 K: t. [" i 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响; @* z* \* x0 z7 a- Q$ @* @
重心位置: [2 N( |4 n u8 u# k4 Q
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
" h/ M1 J- j) ?4 J 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大6 x( E( ]5 n: ?1 y' j, @
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。): X) X6 A/ f2 z* d, Z. ^) p
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
, \' q: q* W. E, q4 v O' e
5 Y( n. F- _+ v) f# }- y控制程序# v0 V5 Q' `! k4 A) U" `; I% a. o
运动过程控制
6 d# S& E! d" f6 g Q' q' | 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
3 g- [: [) W. S$ J' m
4 w4 _( I* i8 V. i调试与运行
$ J3 N5 W9 F) N& |- g& G) R! t 轮子转速调整(车轮大小的设定)3 E& m2 S' m, }8 g- L( m" _
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
' V3 ^% x3 w! w- j1 U 起始位置车子正方向和直线间的夹角3 s! [9 {& { l3 @, e9 t# T, e
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ' ?+ W0 t6 t/ y4 q
! C( N1 l, `# g( ?
+ |; M+ K( Q) b+ h. h
然后上源代码:
+ x0 b. G( b" S* B. m- importlejos.robotics.navigation.DifferentialPilot;! m* X$ [2 m) {6 b" s* n' Q
- import lejos.util.Delay;
2 l9 k% r: ^+ ?; {- Q4 {
. ^1 S4 j. b# N- [- /**
3 S7 d0 }, J% F# s2 P1 f# G( L O - *Robot that stops if the buttons are presses before it completes its travel., Y2 P. g8 x! I% ~% G) m
- */: f2 K, ] \. Q) i- |0 p5 d; @
- ; L" f& h+ |& k. T& d
- . G2 d. k+ i' h" L3 X
- public class Straight {
5 c2 F4 G n% {; q9 [( n - DifferentialPilotpilot;( {! V) a9 Z! a; f' h
- doubleleftD = 4.3, rightD = 4.3;
0 u4 u: s2 y5 g. d. @ - 7 ~: L$ i5 W# T8 c" \4 S/ c
- publicvoid adjust() {
; m& F7 |" R: b0 r* e - //wait for release- @: n4 v2 S) b2 s' H
- while(Button.readButtons() > 0)
4 Q: \6 }4 ~9 L& a. o( X - ;" Z* m# T& }! r
- while(Button.readButtons() == 0) {
" Y2 r3 K8 m4 F0 _; n+ _1 [ - //input size by adjusting the wheels
3 Y9 Q8 W2 u' f$ W - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
" b$ `7 a, d& v; a - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
) P# u' x. t9 l' `' E
8 l* |+ p! a! U9 u, J& n- //display the size input- j2 }1 s8 F. p$ V
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);# U6 i8 o; T0 ^8 o
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
' K8 a) l2 I' H& O9 C' d0 X0 j - Delay.msDelay(100);* Z# }7 L' U$ M6 o P# y) y. J9 ^% R
- LCD.clear();/ |0 u. o& C' t: R& K! _: a: D
- }" d' B7 l0 }) k* c. p
; V: ]3 ] D' a0 s/ t: t: B- }
7 h2 g2 c2 C. `6 t. w `4 P
; F( ~: _3 c) S! \; `- publicvoid go() {
/ f b M6 N" T8 e2 X - //准备起步
1 ~' S$ h% S1 Z: b9 `3 a! ` - //wait for release
- K/ V" P( J) y2 ?2 e - while(Button.readButtons() > 0)
6 V' x; A. z2 Y+ k2 \4 j# s* M9 e - ;- ^. P6 K5 }' X8 t! v8 ?4 G: s
- System.out.println("pressto go");- W/ {6 r# d7 x1 e: k* ~
- # B; y0 `" S: Q% r7 |) p) ?
- Button.waitForAnyPress();' t7 }! U* d1 L' m) p ^- b7 E U
- LCD.clear();& I2 x8 E3 D! U" V+ R
6 ?# r {5 H6 j- //初始化
4 V: a/ H& V& p0 K$ q - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
2 t7 b0 z0 B" o8 G - pilot.reset();
0 o8 i0 s7 r3 m( s6 Z) |/ F, E
7 _5 `# C$ s, p- Delay.msDelay(3000);
# ?4 x( F4 z9 t* @
. m# W. y- l: }( {- doublespeed = 10;
% J' s c4 D6 [6 }! g% x - doubledistance = 0;
2 U7 T8 k, `4 e: Y- P/ t
: v8 q {2 R w# G- //起步加速5 Q" G0 ~0 p/ O& u
- pilot.travel(300,true);
2 j; w) M0 @$ _; d# m
; ?) [+ A y! r6 q4 T$ j- while(distance < 20) {
% M" t/ E2 m1 l' l) ]. P - distance= pilot.getMovement().getDistanceTraveled(); h" Y! s% o' J
- speed= distance * 5 + 10;4 n9 W$ g0 G+ @0 o% q0 g' A# g8 F, D
- pilot.setRotateSpeed(speed);
4 C& i1 A$ s$ c7 W- s& O1 S - Delay.msDelay(100);
( b* I# L8 u n8 j7 V# m - }
[. q3 P( `4 d - for(int i = 0; i < 10; i++) {. s* p9 r2 }( V9 L
- speed+= 5;7 l+ G6 \: [$ V% R' H6 g
- pilot.setRotateSpeed(speed);
9 v9 ~! A+ p6 F& b3 n - Delay.msDelay(200);
3 `' U6 M$ q- J1 K- B6 @0 K/ F - }
6 U$ Q H* P, c0 M, m. K% u& Y& c - 2 @! a3 T) y3 Q9 m3 J
- //TODO 减速
" f7 R( R! e% ^' q
& o3 r7 m3 D0 s: E- //停止机能3 Q! F: U2 ^9 u' q
- while(pilot.isMoving()) {
, e! o9 J$ O: \( ?4 `) ?: | - if(Button.readButtons() > 0)
0 ^0 e+ ^/ @4 {- x! a* R - pilot.stop();0 B' @, M$ U; O2 }+ w v
- }
# ]! G: q8 _0 l2 M ?# x; k: }( }
: o/ c) ] x2 _ N& U2 P- System.out.println("" + pilot.getMovement().getDistanceTraveled());( E1 a5 G; i6 \
- System.out.println(-Motor.A.getTachoCount());
! @, \- f. s$ r) m* ^ - System.out.println(-Motor.B.getTachoCount());* H1 o- c; U" ]9 J* _& {
- Button.waitForAnyPress();0 L R3 F: H! M; v1 A
- }
6 ~7 E. h' ]/ F" }4 d! I( t5 Y7 k$ G
$ F, {) f9 ]( {2 |/ d! k- publicstatic void main(String[] args) {
" D; T3 I# E4 J - Straighttraveler = new Straight();
2 e, U8 D+ y0 z
4 b( c* `- H% l" T/ y- traveler.adjust();
6 B4 g, A) e( M/ u# J" N& J - traveler.go();
' Q" L" n9 T( T4 u - }
% W6 y" e8 P+ v- ^5 ] - }
复制代码 % \. Y$ @) O2 k9 P
|