本帖最后由 hello怪 于 2017-7-25 22:24 编辑
1 a/ m9 h1 J3 ~5 \2 p
( m! K/ Y7 g) i7 ~$ f0 _(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html 5 B: N" M2 \4 s& K
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 6 t+ U v, w; s
场地/ @$ `6 w1 D9 {* {' T& \
水平度和光滑度 在家里当然瓷砖的效果是最好的2 L8 c; k4 |' V7 {6 T3 v
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直$ \2 \, ]5 c! I. m0 _, k# ?
/ G( u% h0 v1 W4 w
车子结构
1 k: S2 B+ h& {1 B% U4 X 轮子间距
- p& A0 Y, u8 X: w8 U) y; [ 轮子间距越大越好,稍微想一下便知
7 S. {4 j4 R7 I0 t 轮子大小
; }; Z# B! F, [+ z7 B7 s% I' _5 q 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子), V& L5 T4 R: `& a! a$ ?
随动轮的设计
O1 w2 D- d S7 X 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响9 s+ I" w# k& r; F2 E: n, O
重心位置
: _5 d, |3 k$ \" j9 D3 r9 X K 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小) t3 M% x8 k4 C
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
; p5 j1 U# i. d' ?; ~ 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
# x. U+ p8 _! F+ K- v5 C 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
$ p' Y" C% J2 ~, B2 [
0 W: W; Y1 Y+ s p控制程序1 _; T2 A: \: c' j3 Y& S( S
运动过程控制$ i1 A+ u3 u8 \0 C/ b9 f
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
* s- t/ W$ l/ C
, \" |% M* j8 g! }: k调试与运行
& H+ F. r/ d) j1 G9 C$ S4 r 轮子转速调整(车轮大小的设定)9 b! D" G1 [( k+ Q
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
. J* h B; T% r- A$ _! F0 q 起始位置车子正方向和直线间的夹角3 p9 |; O7 W7 M' B5 n. p0 {
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 . @1 ]: k5 K4 m6 g5 f* s
" q1 S- m1 N5 A# `+ p+ q" S& P
" i" l0 a* i9 j% {
然后上源代码: - 5 \# x% |$ S2 R* M1 r
- importlejos.robotics.navigation.DifferentialPilot;- p1 r# N4 i+ l/ v% u/ y" \+ a
- import lejos.util.Delay;
; S/ F' E h2 b
l% b+ D" M8 A0 l% ~- /**
3 y1 B+ w) _. S# |: |+ \4 K! F - *Robot that stops if the buttons are presses before it completes its travel.5 y+ {. X9 n5 m. m# Y" S& K4 h* e
- *// y2 r @- ^9 I' q% T
6 _5 m9 V( L$ R2 ^1 g# |
% I4 G* R9 D+ X4 s$ }- public class Straight {& e: O a1 a. }- R8 ^4 U4 e& H! U
- DifferentialPilotpilot;
+ o& z% c- r j C$ i- u; y9 u$ k - doubleleftD = 4.3, rightD = 4.3;
! }4 i5 \6 o$ F+ v1 I
$ p& _4 Q0 S" x' ^- publicvoid adjust() {
; Z! _9 h. J. Z0 J! u; M - //wait for release7 f) v# O" ?! E8 R5 ?
- while(Button.readButtons() > 0); Z4 f0 j$ }1 _; n& A) I( k, }0 ?
- ;
- K# P: f$ ~2 E$ D% _0 i! W - while(Button.readButtons() == 0) {
0 I3 u8 S+ c# B( M. L. x: q - //input size by adjusting the wheels
8 C5 V2 P8 s/ }# W - rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;: N0 z6 v, K( `4 \
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值" n7 u+ ?6 R& r9 L8 w6 j
- ' c1 G: {0 e5 t3 R" x0 `
- //display the size input
. g& K, j9 ]; {+ ? e - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
: e0 L- T8 u! o' q4 ]! n - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
1 b5 t' K! v s, H - Delay.msDelay(100);
) I/ q* w% L+ F - LCD.clear();
. o4 D0 }9 }: t# A% f7 ]' b9 ] - }
& o5 u( T' |3 x+ `! J
( E8 R% V: {0 ~- }
4 u/ q) x- a4 V# a
" ~- ]% q* Z4 |! H) w- publicvoid go() {
. ]* o: O" y. s8 z9 ~ - //准备起步
3 |9 e: Q* V0 c# [/ Q/ E% I - //wait for release
1 X$ I }6 J9 y6 A" I# v O - while(Button.readButtons() > 0)' w, m6 u; L. c+ u; O7 O
- ;& `, ~$ C( ~0 r" A" K7 d6 [2 q
- System.out.println("pressto go");& f8 y! A o: A2 d
/ | a7 h3 W. ^% l+ H2 g- Button.waitForAnyPress();8 Q3 E9 p. ? R* G) y0 G, r8 P
- LCD.clear();& g+ M, C+ J3 Y" i! J! E
5 g) h- u! I& q$ B6 `' w- //初始化
5 }, R4 e5 V* X7 p5 Y( l - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);# }: o3 a. V& r, O0 ]7 \" O* a) h
- pilot.reset();
+ H7 m1 A; j0 T) h9 k9 k7 k' M8 ?
# Z# P: G% C; t; O. |- Delay.msDelay(3000);: @' J* y. E- V P/ t
. A# u/ ]- V+ X7 [4 _- doublespeed = 10;
& i% X+ o5 P; Y6 L# A9 _6 Q - doubledistance = 0;8 H+ z- l, W+ D6 L& ?
- % U6 {$ C6 G+ {# o
- //起步加速, T+ F4 t" p' Z6 V, D
- pilot.travel(300,true);
# a% Z9 w3 A6 U
( m4 ]( O8 |7 F( d$ h0 Q" ?+ f. l- while(distance < 20) {
. @" h7 s$ G. l2 k: E8 |4 A - distance= pilot.getMovement().getDistanceTraveled();/ V' f2 A4 C+ f( l0 B- B
- speed= distance * 5 + 10;
) b' t& s. i0 O L3 a+ R4 ~* N+ d - pilot.setRotateSpeed(speed);7 Z7 u) i _* L8 [) g! L( K
- Delay.msDelay(100);0 \* n6 w. x% ?% }' ]# R
- }
9 |2 S7 ]1 @9 M. e) y1 ^& L0 j - for(int i = 0; i < 10; i++) {
$ d% ~: |8 y2 S5 w: a d - speed+= 5;4 f+ L9 i9 C ~2 c; \3 d8 g
- pilot.setRotateSpeed(speed);
5 ]& B# @5 t6 s0 Z8 d2 i k; ] - Delay.msDelay(200);, J. m6 |6 I' B: ~. H
- }$ m) o& A& I! H, U8 D' |) \- V) h% W
8 U. l h6 {3 g% L- //TODO 减速" i6 ~4 @( ?- H+ `: Z/ U- ]; D
- 1 U) P8 }0 q6 D* H3 A; o/ D
- //停止机能
! P+ G. u4 h; q1 q - while(pilot.isMoving()) {6 R! l& y4 {$ c& B
- if(Button.readButtons() > 0)
: _% W- e, X* j+ I; f, ` - pilot.stop();
; t7 O) l1 a; I3 H/ w8 x - }' D5 @& L1 Y1 _: k* x
- 3 P' Y8 w. p" h% W1 T# ^
- System.out.println("" + pilot.getMovement().getDistanceTraveled());1 }* s3 T0 k# H: v! C
- System.out.println(-Motor.A.getTachoCount());
. ^) @. A/ A. U5 c- @4 d - System.out.println(-Motor.B.getTachoCount());- \4 S1 Q: j7 p/ F ~% J
- Button.waitForAnyPress();8 R0 @( I# t3 |0 L
- }, a/ @8 ]! S9 F
}& |, }1 \1 P- publicstatic void main(String[] args) {2 S- Q) i" V1 S6 ~' B; ]
- Straighttraveler = new Straight();5 ~4 \& [5 Y( o: [5 u5 U
8 l; l9 x y9 n& q) B- traveler.adjust();7 t$ M4 G9 Z/ g1 _9 u
- traveler.go();
: ^% ]8 c+ x2 w M- a. a) S) ? - }
' s" T4 l5 d- {2 P. L6 N' f - }
复制代码
6 Q5 E/ [* i P3 G% Z+ [0 l+ y |