本帖最后由 hello怪 于 2017-7-25 22:24 编辑
+ R4 P% e/ {1 ?5 p! V ?! U& ~; G: |; q. w7 w- k
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html ' _& C$ K ?1 T' r0 a0 N" |
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
, g+ [5 Q% O" ?: e, I+ ^场地
( F7 K. v& f* L. t' B# o% o7 A 水平度和光滑度
在家里当然瓷砖的效果是最好的# K4 { B$ X7 ^1 Q7 P/ r) C. E
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直7 a9 {4 s7 ]. Q" y" @) N
' R. }/ i! Y) i* Q' Z9 f1 K5 [车子结构
9 m6 {6 }! {: C S! X 轮子间距
; P9 S1 O( [! v! i+ x: v. c1 V$ T 轮子间距越大越好,稍微想一下便知
; F9 B8 [3 F5 l1 v* [! l* R+ B- @ 轮子大小; M4 v" F' }6 V) }' N
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
) y1 E% l( L/ L8 y0 }* u# _5 B 随动轮的设计
- {' A3 x, i& f9 M 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
+ U2 `6 o! x) t4 ~! F 重心位置
6 r! z" B4 T X0 `' a/ M 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小) Q1 E5 U; \& g- r! r* @8 d
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大/ L7 X, r E: _1 d8 [
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)0 Q* y5 v* y( v" f" c& |
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动3 J7 n4 v, ]. Z( u" L: I
! ]+ K- A! `% g P2 o控制程序( b0 a* [. d2 E- @2 A$ h: F6 Z# x
运动过程控制
" n0 J" q: n! O- v2 ]2 I" c2 | 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)9 _" [2 \5 _; C- Z: e
1 O7 Z( w! B9 j/ @调试与运行
9 o! w+ {9 |( s9 N" m4 }: n 轮子转速调整(车轮大小的设定)' [% G) ^ R; ~- D/ ~5 b
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
1 x. Z; R- R. R6 ?% D) V 起始位置车子正方向和直线间的夹角
! v2 e) T* z& L/ o) \, d5 M 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ( w; f8 X+ e4 U% y
0 a% R. X+ M: _2 d
$ |& s" X w* c# Z- N& ~
然后上源代码:
S# V, p' Z2 c& @- v2 _; D$ i- importlejos.robotics.navigation.DifferentialPilot; k, X( P8 s( z! ~# N. L( H0 D# ~
- import lejos.util.Delay;7 l7 g# ?6 u; V
- ' i9 ^4 z i! S7 g5 V1 d/ Y* e" F
- /**
% A( {9 \; X; t% l' k - *Robot that stops if the buttons are presses before it completes its travel.4 S. I$ L: }6 l( s; x/ e
- */" L5 g5 z! _% i8 s/ ^
- 2 d n% z3 R$ ^/ s* J& n, k- e
% m" y0 M/ p! I9 d) A7 Y: K) \- public class Straight {
5 h) g( f. M% }& I' U4 n. s - DifferentialPilotpilot;5 Q2 M6 l$ D p3 S
- doubleleftD = 4.3, rightD = 4.3;0 o: T* B5 B1 [% w
8 \2 `4 ~: |5 O0 l( G- publicvoid adjust() {
. X1 E8 X% a& c- w' U2 ]2 Z - //wait for release
: e- D j3 k# ~; k8 {- T - while(Button.readButtons() > 0)3 q# L, d8 |! X* g% r; h2 b
- ;" I9 W# X* D- \4 i! n
- while(Button.readButtons() == 0) {$ F, n2 ]7 n5 A
- //input size by adjusting the wheels& Z( d$ O# Z! c
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
9 I/ c% U# J+ F0 H - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
- `! i' r& Q1 M
! q T( h, }; j/ q# L! s. r) W- //display the size input; |) Z! ?# ~! ^# I" P% p
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
- ]+ c r1 q o9 j1 m; p - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);" N7 c' g! Q" e1 \/ e
- Delay.msDelay(100);9 H6 \! Q2 |9 M& S1 W7 _
- LCD.clear();
, f8 B6 S L' v4 t% J - }
. }1 m, r3 z2 P, ^0 }, r - 8 J8 _0 x8 ?5 U' a
- } I1 d" [& s4 c/ M' p) |
' R7 k- v3 p8 P& d2 i% |0 U) e; \; G- publicvoid go() {# c5 m& D9 ]0 M2 D3 `
- //准备起步" ] A, g# G5 Q' u' Y$ \0 C; ?
- //wait for release
& F( M. o& z( j( I' X$ W! K - while(Button.readButtons() > 0)
8 c2 }6 [ l, c; k @" t - ;
, {1 y, @4 `, A# n9 l8 J1 \ - System.out.println("pressto go");5 R$ o6 y+ n* @& c& Q
8 S2 d0 a- x6 H" a" a- Button.waitForAnyPress();
1 Z% R! h' ~1 m( j5 o0 _. _+ E - LCD.clear();
2 T; {" p. j6 f5 S - : \: F* A9 u) J4 l: R0 T
- //初始化7 V3 ^. E9 b: n! a. V T
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
, X. R- j4 a2 p1 R4 M" V - pilot.reset();
* O7 V6 Y/ i* ^9 @
( W8 U1 a8 _0 T) \/ A7 c; B! B5 P- Delay.msDelay(3000);( w v$ x$ h8 ~$ T1 i. G, {: b
$ a* O" A& `+ V8 t0 C- doublespeed = 10;& R" N0 z" u* A: y
- doubledistance = 0;9 w$ v4 {# h2 v' }
- 7 O2 D) p3 i- X( e' G
- //起步加速" S( B! x, z f: T
- pilot.travel(300,true);9 D9 _6 m7 N# z: e4 T `
+ C& f' x7 [" p- while(distance < 20) {
5 W* Z x. `3 L2 D: A - distance= pilot.getMovement().getDistanceTraveled();
: z$ j- h U2 T& I8 F/ e- _ - speed= distance * 5 + 10;
9 e$ j7 B8 Z6 @9 X @1 C" y - pilot.setRotateSpeed(speed);
% F/ k5 y } t, R6 u7 P) E: O) V - Delay.msDelay(100);
H7 [ \# b* ?! ~+ Z/ |' ]; w - }) R4 |) r) T* N+ K: ?4 ~- p
- for(int i = 0; i < 10; i++) {
2 V l4 C4 C P) v( i. d, r; e5 x - speed+= 5;% ]5 b* n* g& f; a
- pilot.setRotateSpeed(speed);
2 e/ r) _% @* O7 c) ^' v7 b- H7 U - Delay.msDelay(200);- f; o. ?1 ~1 V; {
- }
% R2 z. ~ P& F9 A
: ^7 b0 B" _1 t8 I- d& b9 q( v- //TODO 减速$ c" \9 F& v" E+ U& h( |
- * [" ]1 F2 }; j8 f3 {* \
- //停止机能' ^! X/ e2 \5 A6 O& A
- while(pilot.isMoving()) {
. b" Q" W- \ x - if(Button.readButtons() > 0)7 C9 o/ k; ~7 y" l% K: w
- pilot.stop();
) r# J2 ]+ C) ?9 K; X - }
! R1 W: b' a" K6 a% I% ]
% b! |; `: N6 ?6 a2 t5 j& j$ ? d/ o- System.out.println("" + pilot.getMovement().getDistanceTraveled());
* a8 V$ J; B/ A% k( ^9 `! _ - System.out.println(-Motor.A.getTachoCount());5 C) @4 \0 I7 h; d& K, R; R8 A
- System.out.println(-Motor.B.getTachoCount());* l3 E4 i4 q- |" `% {
- Button.waitForAnyPress();
" \- ?# m# I- ^ s7 l9 V" h$ a s - }
/ Q* k) m4 X6 ~% }$ K - ' |! @# @7 P6 ^1 Y/ ~. S
- publicstatic void main(String[] args) {
# g' o% F! T' { - Straighttraveler = new Straight();
* k$ O @! N u
1 S V3 W. |: v* g- traveler.adjust();+ ?- }2 A$ }) V% h5 J1 }
- traveler.go();9 k8 W4 a0 [9 m
- }
5 |7 [3 l* ]* Q, s1 H5 @; I - }
复制代码
7 F+ ?- o( S5 {" F0 B |