本帖最后由 hello怪 于 2017-7-25 22:24 编辑 ) o9 v# @7 j' M# N% K" \6 l
. p; c8 A( w5 G, s8 y5 ~(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
+ X& G: t* Q; H: W4 R8 U$ y% o
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
0 `( r5 z m: H s4 F* s% Y- K0 M( o场地( x* v) g* K1 _
水平度和光滑度
在家里当然瓷砖的效果是最好的* h+ H( S# y% _9 @9 b* h% j
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
4 s& n# o" W. l+ o- v* _2 z4 ^# M5 D- q
车子结构
5 {# b7 P, s; G8 x+ C4 s0 S 轮子间距0 n8 t& x& D7 Y$ M; ^, ]( W
轮子间距越大越好,稍微想一下便知" v0 N" V8 @, C B3 n) \
轮子大小
* d* T: ~7 m; R( O7 d1 t% o3 ^, ] 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
! T1 v, [1 j8 l7 }3 L+ t 随动轮的设计$ \/ l8 L7 N7 `" D. v) I8 E7 q
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
3 w7 [6 C' s3 Y 重心位置
! A+ O# T1 A3 U, B6 {' C3 ] 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
0 M; Z" Y6 @ Z 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大$ _* R. b7 E& {" s! }& Y2 I; N
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)8 A0 E1 U+ _3 U |* {
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
$ ?) H; J9 P3 N0 G
4 m' J( O6 P- w! [& m$ ~控制程序
" B3 B6 h* M: k5 F# Z4 \# E3 [ 运动过程控制( f _' K; v5 o7 ^( a7 o6 B5 F
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
; z {1 p& \( e/ t& Z8 y# C, P6 e7 D3 u' s- ~$ _ }
调试与运行' y: C. j6 [/ S, [1 X. F) u8 i& I
轮子转速调整(车轮大小的设定)
! K1 h+ s, w8 l+ z; [3 D6 F 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法$ i" a( T. G4 I+ ?! P
起始位置车子正方向和直线间的夹角3 E1 f+ @. I* X" |4 a
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ' _4 ?; `$ R, n' S4 d
, q7 J+ z0 Z. u
4 V9 t( ]' P/ h9 E- N+ L 然后上源代码: - / Q+ j6 N; H; F% _) y, F0 {( R
- importlejos.robotics.navigation.DifferentialPilot;
0 j: c9 n- y$ m, z4 { - import lejos.util.Delay;
o% ]1 q: |, Y# Y( d - ! @9 v% \8 Z8 \
- /**6 l# v3 V0 v" f3 p* w
- *Robot that stops if the buttons are presses before it completes its travel.
! V$ s! t1 L% G/ s3 f9 \& | - */. ^8 \$ h9 s3 T2 `# S
/ f6 s$ p; V- M8 H: b- 5 l2 L/ x' F! ~/ [) D
- public class Straight {7 \; L5 C& q# _
- DifferentialPilotpilot;
' k# T% s) w1 X- T7 W* V( g; Q - doubleleftD = 4.3, rightD = 4.3;% `& c7 P2 {# o7 }1 T4 `' u2 j$ g
- 9 Y" b" w! |- s) P9 m, A/ H
- publicvoid adjust() {! p3 |$ V. b2 Y5 S/ _% |; y
- //wait for release, Q+ |6 y5 c' N& Z
- while(Button.readButtons() > 0)
% F. W9 v( k% R* d0 K8 z y& M1 I - ;
) ?! j9 j6 G# N' h) E) M+ P - while(Button.readButtons() == 0) {) m# m" h1 E$ s3 j0 E7 k
- //input size by adjusting the wheels4 B$ A5 M) h+ P3 p. {; U6 q' u
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
; ~: O% K; W8 }0 T ]+ T6 S7 n - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值. h9 g x Z: E0 ]7 p2 @( Q2 @
% [2 R# l6 m' w6 f7 S- //display the size input
" `* Y, R; l. g5 G* w% c# G: f( J( x - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);3 e1 m: y! k* J. D' k2 r$ ~/ G$ V
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
0 J# t3 e, ^$ A; P0 W/ j, ? - Delay.msDelay(100);
$ o8 y# h. x) i& O - LCD.clear();; e6 ]3 R' E T- {
- }- z, o/ Z$ ?" |0 l7 o" {6 d0 H9 N
7 N$ q$ n9 V% A2 e5 v* t5 }6 F/ T1 q- }/ G$ o4 C- g+ p5 p: E& k) u% R, i5 b
& ^3 a# @: l+ Y' L- publicvoid go() {" O# L( H/ D5 v. ?$ v; U) i
- //准备起步
) v0 |5 h' r0 p - //wait for release
; `/ [+ {$ u6 {1 Z( R& w - while(Button.readButtons() > 0)
% ?4 u; A. W: w/ `. V3 k" K - ;
6 ]1 {! ]% ~1 R. l( @ - System.out.println("pressto go");
% n/ x2 W+ U# X
8 V. n- j. |; \/ n- Button.waitForAnyPress();8 j$ Y. \7 u' a2 N# \. k: u3 T
- LCD.clear();+ G$ i6 s& q4 W/ [" k P
" Q/ g' S/ m: i" w/ K( Q6 v1 I1 }- //初始化5 p1 g2 g& K2 Q! T8 l7 W
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);& q; [# X |1 S- j( Y# W
- pilot.reset();2 O( f0 H" S+ i
" o! J b \5 d& F! [0 A- O- Delay.msDelay(3000); v) L' V* t$ _( X1 C C
" H& ~% ]9 O8 Y e( t; x- doublespeed = 10;
; t0 z* h/ I; Z3 ?! B - doubledistance = 0;
, b. Q% m; _/ a: [( R' n4 L. {) | - 9 V) h/ \+ L- g3 l- d7 U
- //起步加速! H/ L. L) w8 b2 w% y) z
- pilot.travel(300,true);
1 i% Z6 r- T# b/ `& a( p' U
" I5 c/ s4 `& _- while(distance < 20) {
, `9 k# i% I8 a% P% J* Z7 c2 U - distance= pilot.getMovement().getDistanceTraveled();' X2 L2 B! M2 o3 {0 K7 _
- speed= distance * 5 + 10;; S6 r; d! ^4 I, ~+ ]
- pilot.setRotateSpeed(speed);
; u) e! u; `+ p1 Z1 ` - Delay.msDelay(100);
P5 H5 P- q$ v - }. U5 e! Q+ p5 Q" ` i9 @+ V# L' P. G
- for(int i = 0; i < 10; i++) {
( }% M9 `, m3 d/ }1 h - speed+= 5;
/ Y# R& {7 H( j# z, ^! |/ E - pilot.setRotateSpeed(speed);/ J; O3 _3 Y6 J S9 c3 e! k8 c. R
- Delay.msDelay(200);& ?$ `4 u1 l0 `5 m! E& P( X
- }
& z: R* `( f b" U, d1 s3 k7 Z
: J4 \& g- C+ B$ ]# Q. B0 T- //TODO 减速! Q, j* w" W* c& @
- E. j' r( X9 ]" V# L! `$ \- //停止机能$ k' O0 \, ?0 k( u* a0 h
- while(pilot.isMoving()) {
* b0 }* v1 H- ^- M' W' @3 o0 N! P - if(Button.readButtons() > 0)# ]6 W% h$ H! P0 _
- pilot.stop();4 o9 j4 M8 }/ [- G0 N) ^; y. j
- }
8 E3 ~2 n/ G: R0 r0 Y
: n3 S5 ]0 m, `7 Y3 ]- System.out.println("" + pilot.getMovement().getDistanceTraveled());
8 D1 i/ u% a I - System.out.println(-Motor.A.getTachoCount());% c- f1 q) K- p i
- System.out.println(-Motor.B.getTachoCount());
- e. ]# \# [; N0 d - Button.waitForAnyPress();
0 q- [6 \( q1 u! [) Y& u7 \ - }# ]2 h; z, ^' }
- * a6 I9 I1 n0 V$ T5 Z. ^$ @
- publicstatic void main(String[] args) {! b) r7 H, i! }4 R
- Straighttraveler = new Straight();
: y0 I- o' I: T
8 O K# o) E0 p4 S- traveler.adjust();0 y4 M! l, i8 c/ b7 w7 E- a
- traveler.go();
2 k5 A# D2 V; a" n4 q Y - }& _2 G* y3 p7 K" X- U
- }
复制代码
$ L7 m1 } S' q0 r |