本帖最后由 hello怪 于 2017-7-25 22:24 编辑
) Q5 ?9 u8 o, x& p( X& H9 B1 ]7 h" |9 A8 |4 w% G
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
6 t3 y! T# l# C5 g) l
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 0 N& {3 v4 K0 h) B$ {& @9 Y- }3 a; `
场地5 T1 `# }2 j$ r7 ~0 `
水平度和光滑度 在家里当然瓷砖的效果是最好的
- e3 h1 ], b! e( k- ^& j( Q, \. o 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直5 X: m4 d4 V) D t# `1 h
- ~$ T7 q9 [; X车子结构) e3 F! q8 C9 g9 i. b1 @! L
轮子间距
9 {1 w1 h7 b4 |# I- A 轮子间距越大越好,稍微想一下便知
7 P8 S: r) a9 I0 ? 轮子大小. e0 S/ m) c) U) a, d! J9 N9 U
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)9 E$ P4 B! Q" s4 L
随动轮的设计
1 A# M5 z9 ~+ Z. U* n& O$ S3 c5 F5 _ 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响# V7 G' i0 x8 l( a# n9 W
重心位置
% h$ _$ ?3 ~: Y 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小. O0 J( Q2 |" |) X$ o; T) Y
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
, B1 ]/ _0 f/ a) T' O5 z/ q2 C3 i 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
q5 x, o0 z/ c, ?1 p 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动0 ]. o7 `' [$ y X# a
. s7 o1 Q W; _, `# }
控制程序3 _# J/ h# |* I
运动过程控制
" `& a5 l2 { d% G3 f$ D 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)2 t! p8 I( J) Q/ m+ i
7 t2 P* } L ?/ K
调试与运行' ~' O9 M D' i2 f2 d
轮子转速调整(车轮大小的设定)
) a% Y) v( v0 m8 U5 o" b @ 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法1 S. ?8 L6 R) Q- m: _' }
起始位置车子正方向和直线间的夹角+ N0 Q( U& ^; g/ S+ y
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
$ W. w) k# H$ d
8 V( L( T- C7 o/ P1 d+ s
2 v# B) [8 ?9 C- C) k5 e, A; D 然后上源代码: - 9 J. W- n3 H; K! T/ j' J4 e
- importlejos.robotics.navigation.DifferentialPilot;
# V+ a, A3 e [' k% D0 `. h- k5 X4 v, ` - import lejos.util.Delay;9 u( L! l% h/ n5 s7 @
- - h. W4 T3 {: K1 O( M: x2 n
- /**
+ v. r H+ J+ P4 h - *Robot that stops if the buttons are presses before it completes its travel.% j. h4 q- [9 {2 E* b
- */* D0 P+ X9 k+ m2 D' ~' F
- + s/ T' E4 b g8 t" g+ q8 |
- 4 G3 |1 a( x G% |7 Q
- public class Straight {
( f# e' W9 `2 s) N - DifferentialPilotpilot;
2 ^, N' l1 d; @1 ]$ D- l - doubleleftD = 4.3, rightD = 4.3;
0 v/ w/ F N1 g9 c* G
# J. W' X: x M& y9 P. S& e& i- publicvoid adjust() {
: _3 s! |0 K# q2 h. x/ x - //wait for release& q" w/ b1 y; Y: y+ M6 G5 s( R
- while(Button.readButtons() > 0)
- x( i3 ?" }6 `2 p1 E - ;; ?# D. t9 H# Z/ [" C
- while(Button.readButtons() == 0) {3 ?2 y" E5 Z4 ]! ^+ J1 Z) i! I* L
- //input size by adjusting the wheels
6 s' W3 D! [- v3 h5 b* S" {% l - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
/ M+ V- Q! j$ F$ i6 w" \ - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值5 X9 Z5 f: U' p, S
: h- g- X: ]) z* r# v2 _7 _' d- //display the size input
, h8 v# K# y* e9 W - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
' W s! n4 D8 \& W! c! _- y - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);. W6 @5 T! ~) S
- Delay.msDelay(100);
4 l1 Q( V- Y; j$ m5 M: @3 R2 J - LCD.clear();
7 f8 s9 u% j4 }, ^ q - }" E" H1 ]- A6 s# \+ v! f
- ! p* z* N+ V- k4 z! t4 m
- }
9 _5 t6 G6 s0 B: ` m, d0 X" f
+ L2 l7 c& `% n' {' F6 P- publicvoid go() {
$ n9 O' L3 ^' {, |0 j8 V: S( R# J- ~' \ - //准备起步' ?2 c2 u5 z5 s* `$ a$ ~! g
- //wait for release
* F) B+ ^2 `- f8 H# P: r$ W - while(Button.readButtons() > 0)
3 q0 j7 p5 ^1 e+ e/ p0 o - ;
2 p" u' t3 @8 f2 Q - System.out.println("pressto go");5 i, _; ?$ A$ {" |0 E3 {2 C( u
- 2 ]/ D3 S/ e/ ]( V
- Button.waitForAnyPress();
0 T, @' {9 T. x - LCD.clear();
9 Q5 S7 N J# u2 R5 B3 W* Z/ g% Y {
4 K6 q" K% H( J6 l0 t% [+ j9 \- //初始化
2 L- [% U. |7 V# O - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);9 k( m2 \' J# S9 L
- pilot.reset();
; S$ [3 D7 B1 m! [ - $ }5 d. s8 X) L
- Delay.msDelay(3000);# h4 I2 C$ y3 @! I% w
- 7 i% q# U$ r# c, b' }# u8 |
- doublespeed = 10;
* n) h X- S% T1 r& m F - doubledistance = 0;
1 d1 ^7 m1 T' }- u, B* z$ G7 T - 5 v2 q) D9 T0 ~# t
- //起步加速$ K" H) n( D7 x) C7 V7 |/ O3 f- [* L
- pilot.travel(300,true);" ~9 M; S2 | X: g2 C3 J& _4 Y. a
- 3 x) P2 J6 x1 ^4 m
- while(distance < 20) {
1 A) y( [( W! b3 j9 l. V, I - distance= pilot.getMovement().getDistanceTraveled();' y' m ?4 G t: P/ j6 b' a
- speed= distance * 5 + 10;
9 L% `) d' V- g, t - pilot.setRotateSpeed(speed);3 g/ A8 p4 ]1 w
- Delay.msDelay(100);
+ D" `; {9 T3 {4 ^2 R+ i% L0 K# A( t - }$ | h9 r I f' w5 Q# |( @
- for(int i = 0; i < 10; i++) {
0 E: c2 t. k8 M3 A9 e1 N - speed+= 5;
9 _( z( j% Q) c" ~ - pilot.setRotateSpeed(speed);
a- @$ c2 M+ ~# {' t - Delay.msDelay(200);
2 l3 v9 J0 _' z7 e* H6 u# z9 M! Y - }8 t- D" d* c- T
{, o% ]4 T4 s- //TODO 减速
5 t8 ~0 Z4 E1 L: @* a2 K4 x
\. a2 h9 S+ @& a2 x) C% Q- //停止机能! q, r2 ~% ~, C5 t" U, k
- while(pilot.isMoving()) {
% r: H! W! y% u: v3 | - if(Button.readButtons() > 0)
2 v" j$ F2 h$ Z% T - pilot.stop();
: H# q" _$ [% t+ p9 u, D - }5 @# T. F! P" {# n3 [5 T
+ S7 o& P7 P- K) A- System.out.println("" + pilot.getMovement().getDistanceTraveled());* A8 [$ G) m$ I# f9 }' U
- System.out.println(-Motor.A.getTachoCount());
# }. [ G& H$ Y4 n# V! y5 n/ W G; P - System.out.println(-Motor.B.getTachoCount());7 D) B- k& C4 T- \3 t
- Button.waitForAnyPress();
2 l, \- h' d/ ]8 e - }
% C6 J7 g2 N$ t4 ~4 l* g @
" W9 i4 S& n! s/ V% w0 R% _- publicstatic void main(String[] args) {
! l( G( W/ h/ H8 T% g3 q1 F - Straighttraveler = new Straight();: D0 F7 L: |3 y5 a: `* }: V! X( v; f$ Y1 n
" Q0 E' w5 n) b1 o2 `- n/ m- traveler.adjust();) ^) [' d" y/ Q4 ]0 v# E5 M! d
- traveler.go();
: T! Q) Q1 j3 w* m - }
) |, n! m% A& _2 V5 @+ O+ s" I/ r - }
复制代码 & N4 z9 q% T1 t, B
|