本帖最后由 hello怪 于 2017-7-25 22:24 编辑
5 L2 Z3 o- S5 N0 ~0 @; @! b* z- `$ P
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
& w* P0 y/ m# t9 {- B" r8 o! q) Y
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: " ?& \7 d% D" F. h, U$ h" N
场地8 I- P4 \2 d, G$ X3 z$ F
水平度和光滑度 在家里当然瓷砖的效果是最好的! |! E# n, _% J8 d
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直 Q; C1 K) {0 Y. _9 [
6 e: D& K; V$ v, ^
车子结构. G; {0 P; c" J# {4 @% ]
轮子间距: d( O! _) d5 V6 F3 D
轮子间距越大越好,稍微想一下便知
4 f- B# ?9 y' N0 U 轮子大小1 N* Z+ G" E# A' \
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
R( R. ?" h' Z5 i0 F9 n 随动轮的设计5 J, J! R7 x6 n9 U3 q' M
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
; S% E$ T, p+ t& _3 r 重心位置
5 [5 X2 q' y; k+ n 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
# b/ d) Z m( [$ S: x/ Y 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
L; |( ], k1 F3 i1 m 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)6 d0 B" I0 Y& @0 q: c; R
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动. h; n. W0 `0 J0 G! C& L
6 B( |; [( S$ M0 \+ p1 k
控制程序. r& U0 {% z. e8 ~
运动过程控制
u0 _, _* L# g* i. f! X+ q 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
' X) t+ I" G+ s8 k; Q+ ^( i# F& F$ j
调试与运行5 A4 z% a# b. i* L Q' s
轮子转速调整(车轮大小的设定)
+ m6 @$ k/ y! f6 Z 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法- D: k6 S; O' p4 y* |2 D# q. I6 o
起始位置车子正方向和直线间的夹角: N% B' v$ ?& K2 r5 H$ m1 {
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 2 g2 t& s8 |) J
& Y7 H& E8 }8 r" J. w2 t% J
- Z2 U: a9 K8 {0 h 然后上源代码:
# ^; }6 J" }( w- importlejos.robotics.navigation.DifferentialPilot;/ X9 O J' X; k4 C4 J
- import lejos.util.Delay;! y3 U/ `6 Z. m9 F# R) r
- * x3 R$ d/ L7 t6 {; M# j
- /**
( W* ^, b* X1 W/ J" {9 L - *Robot that stops if the buttons are presses before it completes its travel.
0 B) K# O Y% I5 J* U6 n - */
6 u2 p/ `+ T" w
8 y8 \, t) X5 T, t h2 z c
8 D3 Q" h! C A- public class Straight {
0 ~) b' Q5 m# I3 ^ N! ] - DifferentialPilotpilot;
$ Y' E5 x% X) o/ T/ h- h - doubleleftD = 4.3, rightD = 4.3;
) z1 O$ B6 i: `! b2 F9 C" L% g - : T. M, G; t [$ U
- publicvoid adjust() {, c+ j. C( {! b. x4 ~5 P' e
- //wait for release
2 ]9 \# D. b5 e! J+ U1 E1 o% g - while(Button.readButtons() > 0)
) a$ [6 ^$ v' y - ;
3 h& [ q* U! V! ] P - while(Button.readButtons() == 0) {+ D& [" G& i8 ?6 t% H, M. _
- //input size by adjusting the wheels
. V+ V8 T" m7 n3 k1 c; d+ W - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
3 z* |& y! v; F5 o - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
/ Y8 U; |9 a: M
K+ e( D- B0 j- //display the size input5 K4 Z4 ], F! ~
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);/ k, `( J5 Y6 m% m! z! p
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);2 k( \. X0 j; E7 T% {
- Delay.msDelay(100);( Z( X* w& S; n3 n# J! v" t8 N5 ?
- LCD.clear();
! i' E% F, Q2 f$ g; F - }
6 v5 Y2 X* e% ^1 q! S" n( |
- k& `$ ^: s/ A; d- }* _) }2 E/ N4 ]7 b) q+ U) b- z6 j
+ f5 Q9 G6 Y2 M! ?" D) h T' m4 o& M- publicvoid go() {* z5 v h! i/ Q0 P8 { j5 e! B
- //准备起步4 W7 d% n( J& n, m) d
- //wait for release
) |1 V$ B4 `9 T: | - while(Button.readButtons() > 0)8 M& ?2 M6 a% d4 T
- ;
$ [& Q" V0 z* L3 i# K3 V - System.out.println("pressto go");
. Q- u2 z. b% I: W2 Y% C% F
; h: ^( B, R% }$ M% n- Button.waitForAnyPress();; C" O, m6 s6 R3 X1 x7 z
- LCD.clear();
4 H5 x- Q* L5 X6 C. w - : \ t4 k6 n9 n `: C' d
- //初始化7 C# O! ^% \0 V, W8 x2 T9 N- a3 p2 K
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);% z* D D* Y2 K5 c- p2 m9 @: j% z
- pilot.reset();
5 f* d8 t/ M' C U: ` - , @2 t; H ?$ \6 R" G
- Delay.msDelay(3000);. B) [, z, k, W; ^! |( e
- - `$ T! x2 ~3 R' d/ G4 p0 y
- doublespeed = 10;
/ K$ f3 j" {8 f9 r - doubledistance = 0;
9 V4 U5 w' J9 p& k, ]' r
% ?( n G, Z7 [, j9 o3 g9 C- C- //起步加速
1 Z" k/ \) A, Q- B4 z8 v - pilot.travel(300,true);9 ]$ w* T' K! r& _7 k" ~
- 8 D `3 _9 o: y7 U
- while(distance < 20) {$ c0 ]0 X" b, Z6 P; K' i5 j! J
- distance= pilot.getMovement().getDistanceTraveled();8 u4 j! U1 }2 q
- speed= distance * 5 + 10;2 n" {& N2 h7 c/ l0 l
- pilot.setRotateSpeed(speed);: E* B) R. ?5 B) N; G
- Delay.msDelay(100);
% J/ n e7 z/ Y g% g - }) o& W* X. q3 j! K
- for(int i = 0; i < 10; i++) {, E2 M% Q2 e, n2 T( l
- speed+= 5;/ I( P2 l7 I) \; L" \; Q1 H. o
- pilot.setRotateSpeed(speed);
+ t4 C2 }& z! m; N! O: B - Delay.msDelay(200);
3 h# h6 l9 W! f6 U - }3 q# [3 G" S8 `$ J; \/ P
' b G/ `+ y, ^/ b4 n$ o- //TODO 减速
3 C) c* Z+ X) j
9 Q! B8 j9 J* n7 z- //停止机能
, D/ k7 V: k2 j - while(pilot.isMoving()) {
* P6 V& P8 J4 W - if(Button.readButtons() > 0)
. r! X$ k5 P! Y" A2 A/ d) \ - pilot.stop();
5 E0 Y9 ?$ N- d: {! P/ O; j. i - }- F7 }9 e3 V; x- L9 h$ f
0 d; E# R8 O7 d' N% ]$ \- System.out.println("" + pilot.getMovement().getDistanceTraveled());
- v# r1 \, z8 @' p* | - System.out.println(-Motor.A.getTachoCount());
7 x! W/ _, \: h; f1 R* D - System.out.println(-Motor.B.getTachoCount());" U& |! f$ U) M8 b4 V h- \
- Button.waitForAnyPress();# F8 n% |. r8 K: h6 {
- }% ?$ L7 D, r9 G( l
7 C& S" J! _9 Z$ g- publicstatic void main(String[] args) {/ [0 R2 S9 Z5 T3 O2 ~$ ^7 J
- Straighttraveler = new Straight();9 J) Z( z+ q/ f* O+ }
' |/ \6 q( q% I: s# c/ _- traveler.adjust();, Z( ?; I: h# _7 r0 t4 h+ @& \: F
- traveler.go();" t4 t) S& g4 r# B
- }6 ]! D' Q9 C. h
- }
复制代码
3 y+ V* ~% y! ~% U' y |