本帖最后由 hello怪 于 2017-7-25 22:24 编辑 0 S+ D8 {3 @0 B: F7 a
' z$ J$ g8 j8 v: K: z& L
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html ! R( R, I# E' k, d0 u
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 2 i U0 l( G. t1 u; `. N
场地& X A8 `# u/ b R* @6 L
水平度和光滑度 在家里当然瓷砖的效果是最好的: b/ K9 |* M) C* g1 N2 A* c
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
$ t2 P6 X- ]$ c# h1 d! U' W% J# I1 P; A4 k" P; L
车子结构
0 z' ^: B9 e" }; ~ 轮子间距
) l) q! m1 \; G6 ? 轮子间距越大越好,稍微想一下便知
( B" t7 B, t- q h! k& ] 轮子大小9 K" C; E4 W$ t2 e0 F
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)) Z, K3 T$ u' r6 |* N2 q
随动轮的设计
/ D7 f1 g* |7 c3 N) ^ 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
% ^0 g9 C& ^3 c2 H6 v: T5 q 重心位置
, l8 I) x; `" I7 d& J3 k. ~ 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小4 t3 `3 K& ] s% j0 H7 V. H
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
. y& k, B V$ c 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
: |% V2 J& H2 V e" g0 _ 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动+ J# j; n" J- k$ B) V; j
6 O! K% Z3 y' Y1 U( o! N+ y s7 \- k控制程序
r- x/ i; b0 _ 运动过程控制
?' `' P1 R9 A1 ]6 y7 v$ u 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
+ d5 M9 }- r& H
- n9 V0 {# G- ~; i调试与运行
, x- p6 p3 f9 g" E; C$ l5 L& r9 v 轮子转速调整(车轮大小的设定)
" W5 {# @: R" z: _$ B3 H0 U 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
! f6 j. b% W9 d1 I; A1 V' b 起始位置车子正方向和直线间的夹角
. Z- P: g( E+ G% ^# R, [ 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
" N9 M* D' h L/ t' ~
$ H9 `0 v J* Z7 w7 Y3 P# h& z+ N* w* S' v5 p1 |
然后上源代码:
% z: R- ?! M7 h7 c. q: y- importlejos.robotics.navigation.DifferentialPilot;* M% }' w9 ~ _' I. p: M* f
- import lejos.util.Delay;
) \0 R+ H3 E, T7 b" h
! z: \, v& B0 n/ D- T- /**
# x V, p5 n1 A0 Q2 a/ ? - *Robot that stops if the buttons are presses before it completes its travel.
( N5 [! d% n% w2 O7 I - */
6 r, j' l$ v# M+ C8 t, u
$ E5 i4 B) v) |. T' ?- 3 u. N* Q2 |1 G$ |; Y
- public class Straight {
7 _. `( @3 ?' h( x9 n0 P2 ^* @ - DifferentialPilotpilot;% v8 p6 \8 W( f& B8 k8 z7 G
- doubleleftD = 4.3, rightD = 4.3;
4 _# C {9 j, c4 @ - 6 F4 g, H h, M
- publicvoid adjust() {6 Y4 a! a9 @1 Z& Z# H* S: i, _
- //wait for release
: ?( A/ H) S) ]9 o1 y( \ | - while(Button.readButtons() > 0)
0 t: s. r3 M. n$ X- S - ;
2 O q. o" ]" M( s+ Q- X - while(Button.readButtons() == 0) {
3 U0 w* U8 Q- f4 E [, q( v3 W - //input size by adjusting the wheels
3 K, F! E" s. A - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
: e; E* y4 r% L s3 k - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值7 X* C7 g8 S" A% g6 V0 d. ^' c
0 M/ c" x3 Y+ k) q* o1 y- //display the size input
; ?4 E G4 n0 B, s# i0 W1 _ - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
& ^' w( v8 |& x9 o) l x H - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
' y8 P* t$ ?! H) l& j- I - Delay.msDelay(100);( L$ e7 {2 s0 R. t
- LCD.clear();
! k7 V, b+ H9 O) c9 y' L# n* Y - }
0 |# P0 L# l5 T- z
* C: s9 T4 J4 N3 a- }, E. g1 U( z! i, d# k* u: r
- $ a p7 x1 s: g! R6 _$ d! Y8 u
- publicvoid go() {) O! B# h+ o& G/ D
- //准备起步% W% ]& F2 x& W' _# `9 Q
- //wait for release/ e. T! P& r2 ]1 j3 L
- while(Button.readButtons() > 0)
; \5 I, {- y" w7 E5 y - ;+ `2 k- v& `$ i1 l |) z
- System.out.println("pressto go");8 l6 {: S7 }/ N r7 Q
- ' F. }2 m. A; p$ n
- Button.waitForAnyPress();0 X* {! S4 ~' I- E! B
- LCD.clear();" n+ Y1 M* `% D B
- . L+ C0 p* X& _0 v; Z- r' a
- //初始化
8 [# S1 K9 S+ n v( x) G - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
$ C0 ~1 r# w( g5 H: L/ @ - pilot.reset();, W$ p) U% R# l! d, \
9 A& h- B5 a) I- Delay.msDelay(3000);9 u2 x9 _3 Q& U* Y
- ' h6 t ?) n& h& p* S4 t6 {
- doublespeed = 10;
) U5 g% T1 q$ f; `4 I$ Q - doubledistance = 0;
7 z1 b$ U. X U) X1 h( e/ I
2 {# K4 E6 z) O, B) y& ^( a- E) z; ]- //起步加速/ \4 _( Z$ P t# d' x9 p1 ?$ \3 l
- pilot.travel(300,true); N& M0 A* [0 g; @2 ~2 b; \
- - S6 I2 _5 [; _
- while(distance < 20) {8 w _, L0 |- T. L' O; w
- distance= pilot.getMovement().getDistanceTraveled();( l* n! K" u$ L" G1 p
- speed= distance * 5 + 10;3 {8 |* \6 q; N A$ y
- pilot.setRotateSpeed(speed);
& _' g" N7 Z6 P: K, f; F- p2 m - Delay.msDelay(100);
5 x; ^5 t. e6 I6 s - }
$ K* q- F0 ]8 m# I) G! E4 P - for(int i = 0; i < 10; i++) {
* N* O" @% O( t7 ^) y# a6 s0 C9 I - speed+= 5;
4 P, `+ N1 @9 z1 t - pilot.setRotateSpeed(speed);$ k# n% F% G' r1 u, r( F8 d. k
- Delay.msDelay(200);+ d# G p3 z- n
- }
4 |0 ]. ^; ?( h& H% y* Z2 I
8 _9 x% [, b1 A. S( O- //TODO 减速
* o7 d9 h5 p. P* o& G% z7 ?
5 \( j M" k+ x, x* n$ U- //停止机能7 ?9 m1 s$ y3 L
- while(pilot.isMoving()) {6 f; ~$ [- Z! X) Y
- if(Button.readButtons() > 0)
+ B0 j; r. d+ Z - pilot.stop();" E; H& T* ~# D$ T) e3 ]+ ~; l' W2 C
- }
2 {$ @4 h9 }, o$ d) ~& m3 ~
4 A$ W. I, z7 p. _- System.out.println("" + pilot.getMovement().getDistanceTraveled());3 W6 F0 o' j7 J! E+ {8 o0 i9 ?5 i, s
- System.out.println(-Motor.A.getTachoCount());) I6 M- H# ?) \
- System.out.println(-Motor.B.getTachoCount());
6 D1 t/ F5 M9 h9 s - Button.waitForAnyPress();
( z9 ]+ Y3 b/ f( ^9 ^ l h# y! L - }% n8 G/ s! q& S6 ^0 _+ e
: ~- L) M+ `. o$ n4 @- publicstatic void main(String[] args) {+ @- i# _" }' i& N* s- D. @
- Straighttraveler = new Straight();
* L9 T/ L( r0 ] s/ z9 m - - U# c! X( r- p, T9 S
- traveler.adjust();; P" f; p2 X3 |6 ]5 B
- traveler.go();+ b9 f/ q& B; L4 R1 j
- }6 t8 D9 Z$ N" H; @' l# c
- }
复制代码 $ j1 X9 A2 Q6 U8 g" o. A) U1 x
|