本帖最后由 hello怪 于 2017-7-25 22:24 编辑
7 d3 q2 X3 |/ ^+ q! E/ K* L! ?
& x2 d2 d, S! ~/ l, K: O6 N+ f(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html 4 V" E) r# A6 F n& h; ^% l* q
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
" a1 K! w- l5 T. e场地
5 m) N9 M2 i" y 水平度和光滑度
在家里当然瓷砖的效果是最好的
: j! q. y$ B$ D0 ^ ~ q/ ^ 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直7 l# [( D4 Q7 k8 @1 S, Z
6 Y' S# v! E3 L2 T+ X) e' S1 P8 t8 |车子结构' G5 o* J8 G3 d# ?* K
轮子间距; F- y* f, n6 @
轮子间距越大越好,稍微想一下便知
* u$ D. \! t! d; b9 i4 b! M 轮子大小6 f6 ~$ d' ~0 L" B
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
, K/ ^) R2 s: \8 @ 随动轮的设计
) x( G9 a+ x$ s% ]0 X+ H0 l 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
5 o# R% r" F) i 重心位置
0 V. Y! @" x+ |4 a; e 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小! {7 ~9 t N7 h$ f4 T; M
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大0 \ J: V- R7 t0 @
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。); v( X# y; G2 z/ r* h4 C8 `5 g
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
" h( I2 O: Q, n: C F3 B* U: U3 X5 c/ h0 b: b5 x
控制程序
" g+ m% l! a( q7 f# T9 Y. z: s5 H 运动过程控制
+ C4 {8 @- S0 Y+ [$ V4 v: R 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零); F! n0 k2 B9 x8 V$ P: r; g' ~1 \
! ]9 j7 U- v1 Y& Z
调试与运行
: y, p+ q, m9 |! p4 I 轮子转速调整(车轮大小的设定)
/ A- \! O. m1 O- L f8 O& x7 l 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法0 q7 ]# T5 {' f9 A
起始位置车子正方向和直线间的夹角
, J+ ^" A) _, d: S6 c: F 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 " q3 Y; l: `* i* |% d
U3 Y _7 L2 x- `% V' R2 Z
$ s1 P1 S' {. D0 X! V, Y1 `8 f
然后上源代码:
+ B5 [! v3 n+ }& H& ]! ^- importlejos.robotics.navigation.DifferentialPilot;
- X& z- w. s" ]1 V3 h - import lejos.util.Delay;
! O& C( b+ [5 u' b4 B0 Q7 A
6 _+ @3 I* c4 }$ H- A1 {! d- /**3 B; Z1 K" ]; H' d4 ^
- *Robot that stops if the buttons are presses before it completes its travel.
6 Q) Y* {# E6 D9 R: Z3 a - */
$ o+ Y- j4 a/ h2 b
/ h( G8 k! c, t& L0 c" u. `, n- 6 X+ L4 [1 s, |9 u& |( j
- public class Straight {
+ w' q ]5 i- O% e) r - DifferentialPilotpilot;
$ s, ^1 v" b }4 ~+ d1 l, K( ` - doubleleftD = 4.3, rightD = 4.3;
5 J. `; Z7 T0 E - 6 g4 f- p4 ]& {6 J; L
- publicvoid adjust() {
- Q: M/ o8 s) c; m- a8 ^' B" c' @7 } - //wait for release
# _6 E$ f& P) O( g2 Q - while(Button.readButtons() > 0): j" S$ g! A( r
- ;
# E6 b a: i6 H& u5 w7 t - while(Button.readButtons() == 0) {& b( |. L9 w" L. J0 H
- //input size by adjusting the wheels
$ G2 u3 h; K& F, g9 ]* L8 Q* @ - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;( F: _. l) _% n4 I1 n
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值. H/ V/ J2 `4 C: f6 J$ t5 m
- & m( F4 y7 m4 I# w! V' @7 m
- //display the size input
9 j% V8 {8 V$ h' L3 ]; j - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
1 \4 f" W2 h" R9 S - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
: o" v: e# a; ~) k7 y - Delay.msDelay(100);
/ i& M. l3 ]& S( ~2 Z: C9 a$ E - LCD.clear();
' U4 \/ R2 ^' D2 _7 I6 C/ {: S - }
; M0 \- P5 Q5 H* d! u
) i* `$ [3 L& a3 P2 r: p- h+ q. d) ]- }/ M. g' [) r/ C0 _6 V
6 k7 t& q0 f6 a. W- publicvoid go() {' C, Z6 q4 b- O. D2 B4 F. D. C
- //准备起步
2 E) ~ N3 a. B3 Z8 c, Z+ K - //wait for release: q6 A7 g# ]! T, w3 n" @5 N5 a
- while(Button.readButtons() > 0)5 ~- O; c# M' Z; h' x2 _
- ;4 l1 u# `9 O! g |9 R+ F5 R
- System.out.println("pressto go");
0 j8 d* s z/ y
: J3 N( y( [2 I* B+ l! {- Button.waitForAnyPress();7 j4 G7 {9 C9 q- ]5 p* [
- LCD.clear();
' X0 L* |* y" G8 U9 V( y# u - + _( t+ S! W( P$ y2 B& ]# }# d
- //初始化
) K# ]2 Z9 |1 z) x - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);4 } N! _. s! |# r
- pilot.reset();
9 Q O+ o) {+ z; B) x) m+ S - $ G9 k/ Y1 {6 f6 X4 z8 ?
- Delay.msDelay(3000);% Y- m$ {9 \" i+ z# y( F1 e0 i
- / l" v# g6 [9 C8 R4 D' D* r0 j, W: l
- doublespeed = 10;
1 ~3 l1 _ K9 C$ m+ ~! m - doubledistance = 0;
! K9 @0 S" v& W* m' @
* t% e1 i/ a# ?4 v- q$ k- //起步加速% N- M' t( C9 I! a6 p. A. |* d/ K
- pilot.travel(300,true);
0 E4 ], k3 q8 r: q8 X- G6 `
" f- F) q4 ]) m5 o% |5 c r3 Z- while(distance < 20) {
1 i9 B1 F; R5 x' a3 @/ t& X4 D8 k - distance= pilot.getMovement().getDistanceTraveled();9 q( j5 g$ `$ Z) x5 J
- speed= distance * 5 + 10;
0 p7 z, C& ?% B - pilot.setRotateSpeed(speed);" n$ R& |( M$ H! e( W- [
- Delay.msDelay(100);$ d6 p' T; @. X
- }1 w: k6 T& M8 L$ b/ @* k
- for(int i = 0; i < 10; i++) {2 m, F" F8 Q& u0 @1 p; v
- speed+= 5;
- W1 ^0 W/ z! F- R0 l - pilot.setRotateSpeed(speed);8 n9 e% C* x2 ]( i% ]0 m
- Delay.msDelay(200);6 w0 V6 Z* |" K: C
- }; S# c+ G% S" O9 z, `6 {7 F P
- 5 T; g" Z1 U3 m& X! M8 P+ g
- //TODO 减速
1 o& @' ]' W6 ?$ c
+ S9 k) Y3 }) i- //停止机能
0 l! U G; o3 O* w: ` - while(pilot.isMoving()) {# C) _. h0 O6 ~. N* \0 i0 a! y& \
- if(Button.readButtons() > 0)# w3 k2 ?! ^ E, W
- pilot.stop();
6 b9 L8 f5 ]7 m+ L5 C - }
& z, T& s" R3 f6 ]. J - 5 L4 d% {# f* \. ^' q* w6 C
- System.out.println("" + pilot.getMovement().getDistanceTraveled());$ T" C" J4 q/ H0 }( f& K3 Z4 X
- System.out.println(-Motor.A.getTachoCount());
& p6 D5 ~( Z; t( F3 f7 N8 H1 K% _! s - System.out.println(-Motor.B.getTachoCount());
) Y/ \4 f; j- e+ {, r- f - Button.waitForAnyPress();3 B' x0 [) g; ]6 X, f
- }+ r! V2 O8 l4 E$ ?2 j( t8 z
1 T. f l6 }% S/ \ O$ G- publicstatic void main(String[] args) {
9 A2 l$ r7 q- K+ t) X. I/ a - Straighttraveler = new Straight();
# q @% j1 u9 U. X' q - 6 n( i4 ~+ l7 P
- traveler.adjust();
+ w9 }8 u, J: P8 A/ ]) L - traveler.go();
% O \/ L$ h/ L' ~8 d/ Q% A5 k8 B - }$ Q& o/ M2 ~% a! i- m" D- Q
- }
复制代码 0 \6 b M/ y- b. F3 j" [
|