本帖最后由 hello怪 于 2017-7-25 22:24 编辑
/ f) V# F3 C/ g) ~( ^7 q
( F8 u+ T" }; c2 O(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
* n D; y. P2 Z6 ^/ R! ]) i
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
1 w5 w$ y: x5 T+ `场地# u9 h# M, M) J$ z4 b- j
水平度和光滑度
在家里当然瓷砖的效果是最好的
9 F- x! J) u7 |$ v 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
1 a1 I5 J0 E8 _& }- E+ H2 D) a7 e* P8 p% D4 g: k: T
车子结构; @& n3 x4 |! ~) P& q0 z. `
轮子间距
- f: n7 `& @' p- x) J* C- h9 | 轮子间距越大越好,稍微想一下便知
/ `& t* `" r8 F9 { 轮子大小, X, {! v- H. b W7 l( t
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)0 m+ }+ `/ L' x
随动轮的设计2 D F3 H" t" |# d- W8 Z
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响. y e0 m# _, y+ T( g% D' f2 } i
重心位置8 Y3 z% l" y$ o. v6 l; h
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小% W6 Z, k1 O) ~0 N. `) u( ]9 L+ y
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
, f7 Y9 C# F. U3 ]8 s 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。); [. r% d6 B W: p! z" N+ S8 H
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动- o$ T- Q, G z! n8 b
& {- k" z8 ^- c& }
控制程序: I W) G6 l/ M
运动过程控制- @& A' z2 D7 Y1 y3 D5 l/ t
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零) u) W. h% e7 ?0 v8 h( k3 @
/ C. E x/ R8 [, {* K5 H! a3 @) Y调试与运行
1 Q4 e: x2 f, g( x9 G- U- x2 } 轮子转速调整(车轮大小的设定)
* `" z7 a/ k$ d7 _" \2 w7 e8 } 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
* ?6 }0 f9 I! y8 F0 ]2 ~7 e4 R; O 起始位置车子正方向和直线间的夹角- {5 `4 l" r& k* c
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
0 e* Z; m, H! U, I) T" W6 j
' h5 r8 ^ w* {
/ t9 ~7 {2 q: [& i i3 `$ Z* r 然后上源代码:
" O: i, B2 z; e- importlejos.robotics.navigation.DifferentialPilot;
5 r5 E) @: s& K! k; p7 I- ^7 d - import lejos.util.Delay;0 \2 ]3 L' }1 J
9 P/ `% d9 S8 c4 [7 t8 _3 G1 b- /**
4 j9 n* u! d2 K4 p - *Robot that stops if the buttons are presses before it completes its travel.
0 z5 g# k( ^. M4 C: W - */
/ \0 s0 t% I0 v/ ^: L( Y
) U& p8 R3 g0 P5 c
* T/ O% _ T: M- public class Straight {
- p1 X/ U- d7 w; a" t1 h; J - DifferentialPilotpilot;# D* l( b3 `( M
- doubleleftD = 4.3, rightD = 4.3;- i( x2 g1 w1 O; U" Y3 ~
# R/ U7 C% N! `) x( H- publicvoid adjust() {
* Q8 L5 x0 ^ w - //wait for release1 I' f7 `7 K! I: P8 I
- while(Button.readButtons() > 0)
# \/ Z# T1 T5 ^* ` - ;& ] H+ ]3 R; R; p2 M/ V
- while(Button.readButtons() == 0) {
' X" ]- H( ?# W& C/ E9 w5 ?; s - //input size by adjusting the wheels# {3 C# ~# G, |! z( J
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;/ _. b) K% S( j7 t' G- j8 d: c+ Z
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值( x# x: H8 n) n9 I5 q
- 0 l2 R6 o% c! J3 n, _/ j
- //display the size input. D2 l1 n$ N2 t% |5 ~9 V
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
6 S5 [5 C! F: m3 J# A& t - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);" ?4 e0 A( Z3 _# x
- Delay.msDelay(100);
5 @! T7 J( {$ H2 P, n8 c' ^ h - LCD.clear();
5 d/ \/ A) N( b {. E2 t# N: X - }! J5 N( @# [& l8 {, f) m' z
- 2 B% I' z$ g- f9 H: p
- }. d* \/ P2 f% P* ]: s- Q/ G( s+ e
% j- K$ e* ?: L& C- publicvoid go() {
* P& ]: L3 W6 a+ d' k9 z8 y - //准备起步
! _ E* U* J5 @* S1 g1 K- [5 h - //wait for release7 c* V- e4 @& h# f- S4 p
- while(Button.readButtons() > 0)* O. E! F; Z0 W$ P6 c) j9 t0 a
- ;
. }5 Z& v/ L2 f+ ` - System.out.println("pressto go");
; x2 w0 S+ n" M' p. R9 G. }8 R p
% p5 T- P5 \) j5 _8 G* E- Button.waitForAnyPress();+ g* D ^' k0 a/ @
- LCD.clear();8 @, M* F0 _ ~8 A2 k1 t- \
- ; E0 S) Z8 W# N7 f X" J ?
- //初始化3 Q( Y5 m( q, l9 |; a( ^1 U
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
" E0 k9 L$ v6 `" m - pilot.reset();3 h2 x ]0 x8 s7 F6 h/ {" y
- : ?9 `9 D: j) s; w* }* ]8 y
- Delay.msDelay(3000);
7 I8 A7 u* h8 P [/ {) H' j1 c - * A! Y3 O1 f7 y/ L3 _
- doublespeed = 10;
" V3 F. X/ \. r1 V% {! q - doubledistance = 0;
* N9 C# T% ?! X& W! G0 D/ q
) b& C1 F5 g. {& N/ t/ y7 J/ D- //起步加速/ R8 y/ j% ^1 T. `4 F+ A
- pilot.travel(300,true);
7 {0 w, h1 ^0 F: ^" @! n) @
M! a$ ?' o- a! }+ Z# T- while(distance < 20) {
6 ?' {+ ^% v, p5 ]6 l - distance= pilot.getMovement().getDistanceTraveled();
) e7 m, |; S$ P- K, Q6 B - speed= distance * 5 + 10;2 ~& D+ [* D8 u' H8 p- z N
- pilot.setRotateSpeed(speed);6 [- \( I- w" \6 u; F5 e8 p9 Z) b
- Delay.msDelay(100);
1 H! _; {0 E, p* U - }; x) H* s6 T0 }& ~+ S1 [5 l8 K# C6 M
- for(int i = 0; i < 10; i++) {; A+ o) W0 }2 q7 e
- speed+= 5;9 M" [9 @* B+ v1 b
- pilot.setRotateSpeed(speed);3 w$ t4 m$ T) V8 G
- Delay.msDelay(200);
; m. m% L& }: @$ {9 Q3 H* u5 I) p - }0 \/ a; W8 c; B- d+ A/ Y
% k o, l" f$ {- t1 R- //TODO 减速
- q. F$ k1 h. d - 3 }- U6 H5 G7 \
- //停止机能
$ Z$ L/ t, z y* }' T7 c# r+ B - while(pilot.isMoving()) {
B8 S# a0 r0 a4 a - if(Button.readButtons() > 0)
3 L. ], K: [, C9 q! u - pilot.stop();* i+ u- F, i" F N" k# R6 q% Y
- }1 B# o) X ]4 ^/ p
$ B2 N7 Y$ F! {- System.out.println("" + pilot.getMovement().getDistanceTraveled());
( ^5 H3 }" Q# P4 a9 K - System.out.println(-Motor.A.getTachoCount());7 ^; z. `9 ~% `8 Q! C3 |
- System.out.println(-Motor.B.getTachoCount());
5 `5 R- g# G: q7 i: w- l; [ - Button.waitForAnyPress();
" `7 j3 R0 ?9 |: X7 o - }
, \: [6 b3 f/ Y+ H - , L9 c! X9 [3 v8 V
- publicstatic void main(String[] args) {1 m* q3 H: _9 x) k4 i
- Straighttraveler = new Straight();* {2 b! l8 z. u( N) p4 g
- p% R* Q; ^- M! ?- traveler.adjust();
. L1 r3 b* p0 z! z; E - traveler.go();
- z8 q, Q8 H* E' s - }
8 ~( H8 j- J5 W5 ~0 M" X- [ - }
复制代码
$ |6 `( c2 U6 \ |