本帖最后由 hello怪 于 2017-7-25 22:24 编辑 - O4 \: `7 V* @1 W3 g) Z m& X' {
, t! s6 l1 ?; ?. \; `
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html 0 J) o5 L8 B: m3 I
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
1 }- y% K, ]5 \# N1 b0 M场地
9 P& k Q7 L& }+ ~4 V4 K. [& s# R" Z 水平度和光滑度
在家里当然瓷砖的效果是最好的
% `) P+ w I- k. I+ B8 r 线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直& d- [5 W# f$ A, j9 A
! W- ?$ c. M% _+ O% ?车子结构
$ D) O+ @3 ]9 Z' q 轮子间距
1 }( T7 `1 |0 A; K9 H. ?5 J 轮子间距越大越好,稍微想一下便知
" H& o1 z7 x' | 轮子大小
) X' M5 q9 m: q% {1 c& n- K 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
8 J+ K" K1 V2 r& y" Z 随动轮的设计$ I- M9 s Q' g& h0 c
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
4 K8 b3 h( d" e$ q L7 v, y2 `5 C 重心位置; q; O. `( X0 f, s
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小5 ~6 \7 f- G+ G8 C5 x& Q
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大; v, |1 o. D5 t3 c
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)* @0 H* p! {9 P. C$ K
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动) e9 Y6 ~/ l0 T& f4 a2 t& |8 s I# k
- a. b$ q2 o- i4 w, [
控制程序
' T& H; q( f3 Y; ] 运动过程控制8 r( ]9 F8 }+ u$ Z! \; w% w i E
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
/ ^. h$ E! V+ n4 z8 ]$ g
/ @- y( }5 [5 E) T7 [/ ~7 K) B调试与运行
9 I0 `1 L6 u& |8 V- b9 t 轮子转速调整(车轮大小的设定)) i( n# Z. t* d" g$ @3 g: T' ^
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
5 b J. G7 c" F; W4 b 起始位置车子正方向和直线间的夹角
( l+ P% Q' ^3 r5 N$ \ 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 & ~. `8 ~* y; X$ b4 [/ h6 L, h
, ]! E7 X v4 o" m4 Z$ m
0 O' W# r7 g w. W- \2 m; }7 F; `! G 然后上源代码:
3 O) z4 }5 J$ @2 i3 r$ `2 S3 I$ g- importlejos.robotics.navigation.DifferentialPilot;
* J$ k) }( v- x k p# u - import lejos.util.Delay;
8 ~* ?5 ~+ n0 L, Y' \4 T - 0 H! J( ~6 b3 E3 R' z% f. f
- /** H2 j: C! R3 ]( e) j9 D. ?$ {
- *Robot that stops if the buttons are presses before it completes its travel.! c0 s; [5 ` l& n, W/ |0 X* n
- */& E A# ?2 i2 ?9 F i, G6 e, H
- ' Y0 N1 Q9 P0 y* N# z( R' ^7 s
- 3 V0 G6 N! N* l6 m/ J a
- public class Straight {* o7 R" h" q5 _- D
- DifferentialPilotpilot;" @& Y. C% W, J$ |( h2 J
- doubleleftD = 4.3, rightD = 4.3;
( t/ {# {, c& y$ v
/ |4 B- o' C1 g- publicvoid adjust() {
2 i, X7 j% h a8 _ - //wait for release" R- D( }: B* i9 L
- while(Button.readButtons() > 0)
$ g: f8 U* `4 H, t2 Y. l - ;
) ]9 A2 q1 W8 K K& {: I - while(Button.readButtons() == 0) {
/ f4 F1 n; n7 d3 I# V" W/ \ - //input size by adjusting the wheels7 H! d K, O. e$ y a
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
, }6 d/ x7 c0 M6 j% T - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值2 [; d" R; }, `/ A t% l/ v5 G
- ( K- {3 l+ e) }+ f
- //display the size input, r& H# c2 E1 O- {% }# P& j0 z9 p/ x
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
# |; y6 |& S. }, a$ q - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);: T/ U" B0 a! W2 L9 W7 `
- Delay.msDelay(100);
( {+ Z" f: U% {% H& x4 ] - LCD.clear();
^4 z, d; T0 I4 \) {9 U - }
( r! I; m" k3 ]" I# t
- e8 y0 ]6 o' d8 @( t9 C+ ~9 u0 M- }
7 S& s! a0 A" }8 `+ i. V
6 o: N) C' r$ F- D- publicvoid go() {
) P* c( [5 s: k) q ~; P; q0 S4 y/ Q - //准备起步% J {! H: O: ^# e y- f) F
- //wait for release% B$ {6 h2 m1 n" ]% x6 c
- while(Button.readButtons() > 0)! L' \; B9 h; G9 r; @+ O0 [: O2 Z' X
- ;" k# Q, @4 b8 P
- System.out.println("pressto go");
# ~6 j3 g& H2 y: Q - . Z& s: z6 w+ n, p' u! g: k( q0 q
- Button.waitForAnyPress();* s* k" V, {5 B$ z% J
- LCD.clear();
& ~: {9 V1 b! y$ T* A$ `9 w0 E; M - 0 X" v' b! @ U5 A8 p/ ]/ r! @
- //初始化( F& G1 [6 Z1 A& u& H
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
- s0 y' L4 ?& }/ a - pilot.reset();7 k; R0 E. l$ y
& I3 V# m; r* Q- Delay.msDelay(3000);
: U6 E9 O. X- T5 ^5 ?0 [1 r! M
( p/ o; [) \2 }$ I4 h! a- doublespeed = 10;+ z$ |" M3 f, a' I2 C) Q7 h
- doubledistance = 0;
6 F' |3 n2 s: H6 s - % R, e/ w' Z" D; R+ ?/ l) A
- //起步加速* y& {% g* a! }6 Y9 [& L. U
- pilot.travel(300,true);& q; [- W; W" K8 b$ R# f: a" L; @
- ( q( N9 F7 V+ W1 H3 O( g; x: ^
- while(distance < 20) {
4 |# @+ _& \: m. ^ - distance= pilot.getMovement().getDistanceTraveled();
, A" K" {5 C( N' p g8 j - speed= distance * 5 + 10;
3 m9 ]; o y; @0 o+ @& ` - pilot.setRotateSpeed(speed);; x: j3 L/ `" O/ y+ I. c
- Delay.msDelay(100);
* _4 ^' X* l* a' B- `1 f - }1 S1 ]8 x/ ^1 ~# X& v6 @; ]7 I
- for(int i = 0; i < 10; i++) {
1 N+ Y+ }5 W3 y% @- @8 M# | - speed+= 5;
% @1 O/ F& R' h' g - pilot.setRotateSpeed(speed);" P' h& Z# c6 I, d+ Z
- Delay.msDelay(200);2 m0 `4 I2 s F$ ?$ r8 n: e
- }* j$ `# V2 ^- d: x7 u
4 w5 N* O- b- m4 h9 K9 H+ q- //TODO 减速
/ P8 K) K; t4 s, P8 n; Y% ` - & X [7 v# \ y1 t7 V4 |
- //停止机能
* Q( K4 d6 w/ ~( E - while(pilot.isMoving()) {( l$ u; S$ L5 T0 P& [( g
- if(Button.readButtons() > 0)
6 ~" s$ S' C( O - pilot.stop();
8 o$ y1 e. x6 F( {! p5 [' q& \ - }
" Z1 R; |. z+ M8 ^2 S/ Q3 C
3 }; J1 ?+ W$ Q" b* S# x. e7 W- System.out.println("" + pilot.getMovement().getDistanceTraveled());
; w2 h/ m# e, J- b8 } g2 m - System.out.println(-Motor.A.getTachoCount());* T: Q9 _8 E! }3 b% `! Q
- System.out.println(-Motor.B.getTachoCount());
' R `5 i, x" {7 J - Button.waitForAnyPress();2 Z) I: m4 _' a! R( b
- }; @8 e( B; D8 h" N
- + Z7 P1 I5 K! d( Y8 l
- publicstatic void main(String[] args) {
5 ^ ^8 d2 x# {$ @ - Straighttraveler = new Straight();
! G3 h3 g; F$ F* j& K
3 P- V; W, J% I) T t- traveler.adjust();
: Q" L# M+ E0 l3 |- a - traveler.go();
% @/ k) f5 U% |2 C! F - }# ~. @8 i% \7 `
- }
复制代码
7 ~) f7 K( |- o; g2 d; n) i |