本帖最后由 hello怪 于 2017-7-25 22:24 编辑
6 v0 b7 _6 j2 n& g8 S: t* K9 A
# K; w: I/ t: L3 b. }(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
( P4 ]( w: g0 b0 N3 w
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
[" O0 S! x+ {5 t J* c- ~6 y场地9 k( o; h) _. e3 S( ~7 [) E
水平度和光滑度
在家里当然瓷砖的效果是最好的
; Z* c+ O2 f, p7 k9 v4 t" d; C 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
5 F$ S* n0 s& e3 y ~+ u$ h, B
) R5 [$ R& p# E% M h w车子结构
@6 x. e, O& Q 轮子间距
) A, L: [" v# a/ [0 L" A0 x/ R 轮子间距越大越好,稍微想一下便知% J: \& d& T _( j! s* R
轮子大小
: t3 _5 j; Q" j, q) V* i6 r 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
& N) z. f/ X2 H# `0 L+ \) R 随动轮的设计
/ ^: T9 R" T3 Y. _; }9 Z; K 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
; d3 V; F- d! h' G* i$ p1 ` 重心位置) Z$ M* u( \ W8 t
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
: Z# R* {- f" W2 u' G 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
- g9 s# e' U# O! I% j L 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# P/ s! M" {7 \4 S- Q/ o
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
6 M" ]6 S( U$ [0 ~. I, J- q1 r k' [' e7 w0 a# p8 V
控制程序
# `' C5 u' Q4 f( f 运动过程控制7 p% @* }1 s6 w3 ]2 g. \
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)& S; h0 D1 u4 b: |' H6 C0 H# D
) Z! f2 w4 a6 A D; s8 f s, q
调试与运行
% P& y3 i; U" S. R7 d2 U 轮子转速调整(车轮大小的设定)$ G3 U) d3 w! N& Z
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法; @0 k$ X1 S# Y+ K" G2 C) L
起始位置车子正方向和直线间的夹角
4 n3 Z* m2 { I: Z/ n 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
0 g+ V) {2 ?# F. e5 y0 C9 \
5 u+ q% K( ~' m9 x4 f. q
; U. n. e' Y; X2 w' o3 L4 M 然后上源代码:
* c1 T) c/ {% H( t4 S) v- importlejos.robotics.navigation.DifferentialPilot;, W2 o* G9 {. F- U1 ^- a: b
- import lejos.util.Delay;
, F+ q J6 d8 X) N - ) r& w" y s# H5 _
- /**
6 O5 x7 B0 C+ w" d" I% H - *Robot that stops if the buttons are presses before it completes its travel.
5 H. g/ ~( ]0 P. l6 i% j - */
, c& |$ e7 M+ J" c+ g - % }# a* A1 ?4 k6 N$ z* b
- * @- g$ M5 q( e7 ]3 o3 Q
- public class Straight {
4 \2 t% R$ O% n/ y: R; E* x - DifferentialPilotpilot;
5 H$ I( ]1 u6 U3 F - doubleleftD = 4.3, rightD = 4.3;) ~8 z) H% O! E5 t
) k" A/ t# [( F$ p2 x- O- publicvoid adjust() {
8 r* I5 ~) H; _% G/ X0 w# O0 [ - //wait for release
% R( k; t6 w u) I - while(Button.readButtons() > 0)
* L# j% h3 V# C1 ^( I - ;
( n/ y$ X$ ^. v( { - while(Button.readButtons() == 0) {
( h' T7 N6 C3 { - //input size by adjusting the wheels) p8 f6 b6 }! p6 M' L
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
8 L9 d6 {5 Y% ^# X) g7 D" p4 h' l - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值, l7 ^7 F$ P$ s1 r" W% l6 n
# A) r0 {% O1 ?( E' O9 j- //display the size input5 N: ~1 k5 u$ E! S) @! o0 B" z
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);! N+ ~! w9 ^) q) n; } I/ d" Q/ d
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);# X# @9 A% X% u/ i* {' l3 O
- Delay.msDelay(100);
* i/ M( j' v F* _ - LCD.clear();
2 Q: D5 o# }1 X$ h' K - }
$ S$ F; J" s; C: a - ) Y) U- q: t; d; j( E }) U
- }% y; N. k; O6 B' ^9 s
( p8 Q: W, h( o+ X. q- publicvoid go() {. h& k) |3 ^; W# G
- //准备起步: W+ w8 W8 o5 u; V; M
- //wait for release
7 ^. e( U( C8 t2 \3 X- u3 p; J - while(Button.readButtons() > 0)
% B5 r8 L+ E7 c' V. a1 a; X0 I - ;8 r( B. l2 o; h7 f( b( K% e
- System.out.println("pressto go");) x$ Q e. [6 T$ M7 X @3 M
- ! ]. \ F# ?$ j! e; a/ B# F( [
- Button.waitForAnyPress();
% [" O9 _# a: c3 ^# w# {+ v - LCD.clear();; ?7 d3 L' \; J5 }& \9 S+ r
- : U" O, s G% _4 S$ U1 Q* t
- //初始化
' a) w+ F+ D- y - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);1 ^! t" S: V( R$ `7 U1 M
- pilot.reset();4 N. y! g) W: I4 f7 E
- 1 y( _! j) r1 n) w; N# O
- Delay.msDelay(3000);" [* r: n g) f8 N5 g" g- M
- & s, `1 S9 ^6 \. g
- doublespeed = 10;* u" L5 @2 q+ U; |: a; Q( d: X
- doubledistance = 0;) ^( q; e# S# }' F
+ R9 | ?4 c/ y( }+ w# ]- //起步加速* p7 v* f- E+ D7 @3 l0 v4 O
- pilot.travel(300,true);
0 U* P% ~% ~1 k4 I9 O9 @, ~0 @ - 6 ^" X6 N; h5 w+ N
- while(distance < 20) {
$ p2 b- i. X1 X$ W; j3 V - distance= pilot.getMovement().getDistanceTraveled();, N) f% I" _8 v1 o9 T2 [
- speed= distance * 5 + 10;# I$ g: n8 K% B9 `$ a6 e! x
- pilot.setRotateSpeed(speed);
3 ~8 l9 K; C# x! M, \. V - Delay.msDelay(100);
) D, P; O- o: v t' e - }7 |: j1 _6 n u* r2 g: j& S3 _
- for(int i = 0; i < 10; i++) {& t' `* Y) j; n/ B; t# @; _' h; w
- speed+= 5;
, k" T6 w& X# h% P0 u" v) U - pilot.setRotateSpeed(speed);
T6 T- \0 I. y9 o& H - Delay.msDelay(200);* I* X7 x$ J6 ], C. y
- }7 ^- a1 f3 E4 m* o' ~! U
- 2 s ` ?! Y; G, b
- //TODO 减速
6 M3 {( O2 R% W- N( i - ( U# @' d6 t; c$ G% C: X+ ]
- //停止机能
* |1 Q9 Y' L6 d- c5 v, c: e+ S - while(pilot.isMoving()) {
" E0 |1 O7 o3 g - if(Button.readButtons() > 0)! e, L9 _- o5 _9 K2 v5 \ v; O8 i
- pilot.stop();
$ m: k* j6 U/ V J& [0 i3 c - }
1 x! A, j2 d% Z& c: e; @
$ a4 G7 L. C% `/ X% Y2 g4 F; h- System.out.println("" + pilot.getMovement().getDistanceTraveled());
/ Z$ C0 D( z( g! `6 ]; l( y - System.out.println(-Motor.A.getTachoCount());& q# I" T& g' U' b5 f
- System.out.println(-Motor.B.getTachoCount());
: X! _+ O) t C4 n! A - Button.waitForAnyPress(); Z W( t1 M! P) b8 l. o4 G* W5 \* P6 ?
- }
% F; S' D$ U% N# e
: `3 V: M, e9 k, z6 X7 d7 q/ R/ \) ^- publicstatic void main(String[] args) {
5 v% y" D/ N% P( b - Straighttraveler = new Straight();
6 F* N2 J" g! `% h" C' i0 [1 {
; H E' L2 Q U$ W7 H4 l9 V- traveler.adjust();
2 i% e! e: ~ p3 n/ l. P - traveler.go();
; ]) n, m+ T0 ^2 s* @1 q4 p. e - }3 S+ |/ d$ P; k: a/ F
- }
复制代码 , L5 X. u) `+ {) n4 f( m
|