本帖最后由 hello怪 于 2017-7-25 22:24 编辑 : u! T- ^# a5 w; T: O
% O! F8 H2 H9 S
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
) u( o3 a; B5 B: W6 ?! {
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
& K( @( }1 ]) `2 u, ~# q. B& `6 ]场地
3 H4 \) l g% m$ N' M 水平度和光滑度
在家里当然瓷砖的效果是最好的1 ~8 |/ C0 w: L1 _( {7 R4 o; @
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
E" V5 `$ G* f- \. u7 \( C: S! u4 }' C& q7 u3 D
车子结构
+ y3 @. f/ O8 I& g 轮子间距4 a' C: H' {# R9 l7 b" ^
轮子间距越大越好,稍微想一下便知3 o8 } I5 ^1 \. n; \
轮子大小7 j" S: J- r3 I' P+ c# y: D
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
" s% Y0 l# c* V( K. _ B! Y5 _$ W 随动轮的设计1 E$ G9 O+ M, \. Z
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
0 h' J6 H) n* {9 [$ P, H 重心位置6 u) X" j) g& ~+ G1 S, \. b
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
! L" h1 z3 X# ]. K r' ~ 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大, }5 o7 A9 {; _* w' d# f. m) V
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
; F6 A( L4 D( _! w# Q5 P 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动! E& x1 W$ I0 D, Q6 G
. U2 E$ a/ U6 O
控制程序' Y7 q2 c* c& a. X. p6 f; u
运动过程控制5 P. W) }& W4 Z( i- L( }
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)# Q) r7 s1 `+ v) Z
1 e* P/ [) ^- t' d: a# Q: w- ~, x调试与运行
6 d3 I+ w7 Z& R) K' a 轮子转速调整(车轮大小的设定)
2 l# d, C; u- u* o0 Y 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
3 \2 `& t9 S/ Y/ T# M9 z6 K 起始位置车子正方向和直线间的夹角! K" O8 r! I" M7 j9 _0 Y
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
% M- u* A" d* h9 {9 K, t$ F9 n% r
' T$ Y }( J* G1 x' _& q z( R! k- T& u* I- |" C2 L
然后上源代码: - 6 K3 C- o. J% n0 x+ `* J
- importlejos.robotics.navigation.DifferentialPilot;2 E- n% m. x, _5 g! h
- import lejos.util.Delay;+ n. n8 J* d4 V# r5 e
- 5 x& @. h& @* N8 q8 d3 y, h H
- /**, U m+ i8 b1 e( `
- *Robot that stops if the buttons are presses before it completes its travel.! x* G: ^( H% V4 w5 i
- */
1 U# m' P" s4 d7 F' g) T4 e - ' f' d( t% A. n4 Z8 C$ v
- ( m2 i+ u, ?- B. w" q3 Q( F; r$ Q2 ~
- public class Straight {
* x5 P6 A% e6 i% K- k' Z& C. z8 p - DifferentialPilotpilot;/ b! m$ }+ D5 r0 ~1 I8 H
- doubleleftD = 4.3, rightD = 4.3;- l; p4 t" s& u& e, S( q
9 g- r# [% R# g6 {4 A/ \% t, x$ ^0 e) @- publicvoid adjust() {
# z- w$ n3 `4 D5 j - //wait for release
8 k! k* z/ ]- H+ F1 h - while(Button.readButtons() > 0)5 Y' ?# d" t. m; ~! f
- ;& {: n; P" }7 s, F
- while(Button.readButtons() == 0) {
+ Y0 E( P$ S# w: v5 C& D - //input size by adjusting the wheels( l2 V1 s" }2 C/ w3 q
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
8 s0 \$ x/ f- g- v4 l - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值4 u4 R5 z: i& b. _+ [
- ^; j7 L! w& {7 \! W- //display the size input
* R/ `; l" h: c6 [ - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);- s+ |9 M% Y; _( [/ z- w8 {
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
! ^; K9 m0 k: j# u3 { - Delay.msDelay(100);
! c3 H7 R) ?6 N - LCD.clear();
: |; |+ ~) r- K9 S S9 s; | - }
; E" ~5 `' m. t8 k: }' I d& E: ^! R
$ ^# O! Z1 y' o3 t- }- S! j" q. P' M6 f$ ^
- 8 O4 p, r. J- s. R0 T
- publicvoid go() {+ i& a( k6 B% R2 \' ~+ A: s
- //准备起步: Q- C% m2 L) f8 X1 L5 Z' \
- //wait for release7 ^0 [, ^9 R0 |! r" Y7 o
- while(Button.readButtons() > 0)
. b$ p. s8 f4 s1 L4 [) [ - ;9 [: B( Z2 ^/ g, r8 i
- System.out.println("pressto go");& E n0 X1 Q4 C! p0 |
$ K' B* B# q& f- U- Button.waitForAnyPress();% |7 l8 y8 V; A, x
- LCD.clear();
" F) i$ w3 r3 B1 C: N - 2 Y; P( n' H% S6 ^& D
- //初始化5 I( M* j- ]4 V$ U1 ~
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);7 Y% w' Y2 L( h5 d
- pilot.reset();
7 I/ ?7 u7 h" Y7 O' `( G4 } - 9 g8 S" n8 G* b# S7 L9 a4 K
- Delay.msDelay(3000);
% R& C& m' \, M
: I. P* u! D4 b+ |' ?! ^0 z8 i- doublespeed = 10;# a/ e; h" L) r8 s4 ?
- doubledistance = 0;
k, {0 X# H& {+ N1 V - & w2 b# S1 t# n5 x
- //起步加速2 _8 a7 n3 d8 r; f0 N/ ]- k* g
- pilot.travel(300,true);
0 e& {; i! x9 V3 s. H - / u( J% c2 q! o& _- Y# [
- while(distance < 20) {
1 k ~9 j `2 G% g& V% Q - distance= pilot.getMovement().getDistanceTraveled();. l( D3 o. w$ R; y8 Q% n
- speed= distance * 5 + 10;
# e( f& q% D) [# N6 Z$ ?. v( K - pilot.setRotateSpeed(speed);1 O4 {3 u. M- T' X9 x5 h
- Delay.msDelay(100);- ]( q, g: i. M: z, F @ m
- }( T. z0 k* c. p9 F/ M$ }
- for(int i = 0; i < 10; i++) {* A. T5 }8 s( T
- speed+= 5;
( H2 ?7 s, T, U. A. \ - pilot.setRotateSpeed(speed);
' m' U* N0 r: y. f) f7 S - Delay.msDelay(200);4 i' l# W) x+ \( x
- }, r* L# U7 C/ \1 V$ T
- 3 Y/ g. | S; c- s( g
- //TODO 减速/ A2 [8 N4 I% x+ u
7 ^" N4 h5 l; z+ n& ?' m7 k" ?- //停止机能5 _0 P6 i$ q6 e* T3 C2 }5 D. n; ]
- while(pilot.isMoving()) {$ I6 R! W& q2 _ `
- if(Button.readButtons() > 0)
. R- P; k9 X2 P- h' [ - pilot.stop();
3 h5 Z0 ^5 [ m+ o2 A1 ?; Y - }
, c- K3 ?" Z8 Y P
: C/ u6 t6 @; G! E- System.out.println("" + pilot.getMovement().getDistanceTraveled());7 N6 R2 A/ u) X& [$ Y6 E( N
- System.out.println(-Motor.A.getTachoCount());
" J- _' G5 W3 @ - System.out.println(-Motor.B.getTachoCount());
: H+ x4 Q8 A# Y5 |. ]9 |" L7 ?. X4 M - Button.waitForAnyPress();
6 W8 t c. X7 y& k- Z0 ~; P. Y - }; l1 {& l2 q6 F9 u9 o# i
% s" }4 J: R8 x7 `: |+ r( b- publicstatic void main(String[] args) {' N2 h5 H. Q6 r$ O3 h- v# j
- Straighttraveler = new Straight();, ^4 T0 j& {0 R$ {
- ) U7 t$ P8 x; Z) S( J3 ?
- traveler.adjust();: P* S- c) z' z) S- M \% o
- traveler.go();
" P1 c6 o5 \9 t9 v: O4 X+ h5 r - }! d" e' j3 h( R: P: m/ ?
- }
复制代码 . T& Q M* [0 E, q
|