本帖最后由 hello怪 于 2017-7-25 22:24 编辑
/ B+ G# {, Z7 t% j. F4 X4 T& g
2 j2 I3 p4 F5 J! L2 P2 f( ~6 {+ H(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
9 X. y6 N% y2 u3 V# J
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面: 9 I" l' O8 c# P3 U% I% E& \( j
场地* @# N, W! I3 P1 g
水平度和光滑度 在家里当然瓷砖的效果是最好的. T3 p4 k: B) e+ h0 R! O6 L$ Y
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
7 j. z& p$ [# o9 e" ^0 x
! s `- _: Y+ `+ ?3 s车子结构
+ B, z) d8 J6 @' U/ S1 r2 @ 轮子间距) z( S' y( Q' a% c* u6 m& x
轮子间距越大越好,稍微想一下便知7 z/ b: j2 f9 ]: J
轮子大小* R, S2 B4 m9 c+ U6 p+ K0 p
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)2 {" t1 Z- o6 L% O* S0 U
随动轮的设计
% y& w% A p3 G, Y; Y# q 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响, H) D( K7 I! ^+ ^6 M& O
重心位置
/ F, ]# Q- A L, H; \, o9 e6 H 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
' N8 Q% G1 f. [1 c# P 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
) z, C4 g2 [& D9 p 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)' V! Y% I% Q$ ]
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
# b2 `$ J. |2 e; P! t$ h5 \' J: A, S/ W+ ?/ ~# Y4 |& @
控制程序, k* K5 J3 D) _1 e, ]
运动过程控制
h5 Z( Q. O% h 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零). Q. m' l1 j8 Q" D- Q. a
0 l. {8 \* O9 y( E调试与运行- Q7 F% R o/ Z+ a6 Z6 F4 X
轮子转速调整(车轮大小的设定)' u) G3 q7 C/ Q- p
这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法" B. O! d3 E/ |& b* M
起始位置车子正方向和直线间的夹角* b% j# i" `2 q u$ K) x
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ( Y7 }& H$ a6 Q, g8 n; X) D
# L5 D- `5 k/ ?/ ~7 j1 K$ r
; H; k/ e. W' b0 O" y; ~$ [7 [* N* | 然后上源代码:
1 R9 \ E8 i9 x- s7 n5 u- importlejos.robotics.navigation.DifferentialPilot;
6 `0 H: C7 Q _8 q- ] - import lejos.util.Delay;
- C: w" g% s" E6 \/ I. i; q - ) p, o5 O; m: \* X
- /**1 T: A4 _1 C7 v4 p3 e
- *Robot that stops if the buttons are presses before it completes its travel.
' e! l1 N# f+ [! O! | - */
! F% T$ F& D) x - 7 N% A6 l3 h* l+ J: x7 r- ?) I% p
- P4 \1 q0 o9 D% B& t
- public class Straight { C8 Z7 [6 @/ N( e& [/ ], |( F
- DifferentialPilotpilot;
3 E' x% \' Q' |/ H+ t - doubleleftD = 4.3, rightD = 4.3;3 I. P7 ~$ W1 l5 M \
5 O1 Y2 g: Y0 O0 c4 r8 I- publicvoid adjust() {
. b/ r, |7 Z* t' G/ x0 c - //wait for release
/ G( D3 T7 i2 _7 ] - while(Button.readButtons() > 0)% v! U* x# H6 H
- ;+ e2 Z# j+ h) Q1 h" K+ X
- while(Button.readButtons() == 0) {
% m* G1 M" P+ s' ` - //input size by adjusting the wheels1 N: ?) |4 \& M6 f1 ` r. C
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;/ h+ H& H1 A4 x
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值* Q& {9 O# F+ ]8 M
3 ~4 `/ P. q( `! X1 f; {' h6 L7 L B' g- //display the size input
/ H' A. F1 a# w' \ - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);- s$ X4 O$ e4 a2 [7 M& P p
- LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
7 Y3 }3 |# H J$ {& o& t' y4 I - Delay.msDelay(100);
! l( V3 ~0 ^6 h0 f - LCD.clear();. x+ R& |5 f9 [4 Q5 B6 P2 X) Z4 o, e
- }
: ^2 `) C6 r! S" Z - 8 y2 b: V$ V+ e+ ?' c3 f [
- }
, R2 |; U. \( K1 ~1 y - . S4 S0 Q: M" s$ `
- publicvoid go() {
N% J9 _+ A4 C" O% F4 r - //准备起步
/ k' w' ]$ a( C; d5 a2 C n* S - //wait for release
) A1 Z0 S% x& M1 r7 X, ^" y - while(Button.readButtons() > 0)
|0 R( _" Z, r! ?( j) m: K& e - ;( {; k1 f: O F9 F/ F) O* T
- System.out.println("pressto go");
* j6 o" v( n% U* M9 x7 M @- G6 x
' }6 g* {+ B) x# ~7 W- Button.waitForAnyPress();
" K+ H! @+ k d; T# A" Q: ~0 X, V - LCD.clear();; A8 ?/ C- G+ ~0 z2 _
# b* J6 F4 }7 \1 k3 h, x3 G- //初始化
; u h* \3 S9 c2 d- {3 { E/ C - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);7 _' X7 {' m* Y* C; J; f
- pilot.reset();
: S' n: C0 Y2 @/ w
% P. l: D5 K5 h6 S! B" z) i' H7 L- Delay.msDelay(3000);* S; ~. [' _4 r# u
- # S4 P S+ E G2 _; |. t. g
- doublespeed = 10;
( Q& U; ^: C& _! b( L - doubledistance = 0;
! c' @2 W2 O p" g1 k% v - 5 `1 F! }2 g0 C3 q! A, T
- //起步加速
% m2 } D4 ]: S7 s$ L3 x - pilot.travel(300,true);8 V# X; h, b: i6 z* I2 Y
3 W- L- S7 S: |% z2 z3 l- while(distance < 20) {& x9 q J/ G$ B3 ^6 p% P2 A$ s
- distance= pilot.getMovement().getDistanceTraveled();/ x! ^: }9 P" `: U1 N
- speed= distance * 5 + 10;- B }3 x3 y; P! E7 k
- pilot.setRotateSpeed(speed);
9 i8 F* m) |( U' s) m! A - Delay.msDelay(100);
8 `7 I7 @/ J2 r: Z6 e, a% E - }) F$ j% r5 k/ k1 }+ ^% [4 c% K
- for(int i = 0; i < 10; i++) {
. I. t7 I# `( y - speed+= 5;7 |( t7 {( R$ V" e7 J$ O0 P
- pilot.setRotateSpeed(speed);+ |% b9 r0 w& S/ B' r" h' V
- Delay.msDelay(200);
+ w$ \% U# O1 o# f5 z8 H; L - }
) I! {6 u9 P% [* Y - , s2 e1 I5 z& @# S
- //TODO 减速/ |( U2 ?2 i' A* V" W' S |
- 3 x9 y, S8 @$ W( N! y9 o
- //停止机能
- v+ n7 r ^& K; T1 N - while(pilot.isMoving()) {
; o" _/ W# i$ N6 D - if(Button.readButtons() > 0)
/ N3 N" P" D7 _0 @% B - pilot.stop();( a+ {) \8 A. h
- }$ a4 q$ r! @8 |# j
- 5 o6 m+ ]. d& _; s4 {
- System.out.println("" + pilot.getMovement().getDistanceTraveled());
! M- u% l! A* F" i - System.out.println(-Motor.A.getTachoCount());$ Y& @3 y% D! S% Z( b
- System.out.println(-Motor.B.getTachoCount());
$ F \0 ]6 z) U: o% B5 U - Button.waitForAnyPress();
+ m S2 ^7 L' |0 m - }& Q! @3 M- y# n$ t
- 3 N: ]9 [+ e; @+ m" r/ _
- publicstatic void main(String[] args) {8 @; a1 y3 g5 S
- Straighttraveler = new Straight();
7 W2 W' f' U: r* R) A9 n - 6 {9 m4 j% Y/ A7 V' O. M( X
- traveler.adjust();% u8 e4 ~& Q2 A- n) x4 s
- traveler.go();7 X7 R# u3 W2 Q1 e0 d( P
- }
+ a. z$ k( V$ }* g6 z7 s - }
复制代码
3 X) y* n; o' e8 n |