本帖最后由 hello怪 于 2017-7-25 22:24 编辑
- l$ p2 t. g. v3 M+ m
( x$ z1 B0 W% a, A5 w7 K# ]# t(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
+ I! z/ ?+ n0 g/ `7 e
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
$ O+ n* J9 K( A2 G* C. m场地; f9 W' h* g7 |% ~& y
水平度和光滑度
在家里当然瓷砖的效果是最好的# n, |% l) D3 l
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直: h- ?" |: D9 s3 d& u' r
: q6 c" R5 w: C! O
车子结构
* T4 j2 n0 L, m0 G 轮子间距3 z, I. V* p6 i ^5 B, {2 Z
轮子间距越大越好,稍微想一下便知6 b. w: ~0 ]+ Z8 c
轮子大小, T' b7 }% r6 _2 U
轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
; o; M) `; [, k. b2 g- \ 随动轮的设计* i! E7 I. E5 @, X x5 X `4 d& w
随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
$ V; y, w! F0 \* m4 N 重心位置
9 A$ Z7 K' o* D! Q% _! W; u 重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小 Y( W& @' [. [0 H' @, \+ D% v; F
结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大
0 H8 Q2 P* Z% c* b, w( j$ I 轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# e3 w% a5 f b2 c4 d
驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动) t0 r+ U, \0 @0 U" W
% T" |' {; h T3 }# \
控制程序
! z; V8 h9 s" p 运动过程控制+ \5 v" R* j" f; T, f
好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
) m1 {( V& D/ x) N% V6 K( P' N0 u H% N7 }0 @' O, P- {
调试与运行, D* J2 t5 x. c3 j* p( |. W a: r
轮子转速调整(车轮大小的设定)
1 U( a9 o2 F" d1 `% M 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
8 P2 @/ G3 ?" F+ a4 ^) K& R/ O 起始位置车子正方向和直线间的夹角4 o9 H5 p9 O: ~5 d& \
一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ; T% ^5 v" F% {2 a% l
6 Y# m- ~ {/ h# X# U! R9 D5 Y0 f
! J' q5 }0 T+ k
然后上源代码: - " J: P) o7 {1 L$ z2 L d% V6 k
- importlejos.robotics.navigation.DifferentialPilot;
1 [$ J6 ?. _5 m* H1 L# e! I - import lejos.util.Delay;
0 ~! w9 \% j+ {4 l. _
% P, [6 }+ `' `- /**
. L& e' f6 ^ g9 M. c ~ - *Robot that stops if the buttons are presses before it completes its travel.7 b( t1 }2 c, s2 c* p# u$ I) m- K
- */" o: h# t" Z2 s/ r+ q" H! D
- 5 J! u& w# Z# p% _8 [; m
- $ w, R. }. \8 H- Q; w0 t! x# i$ c
- public class Straight {
4 w) @" T( l! Q2 c" D/ }: M - DifferentialPilotpilot;* G3 Y! c* O8 h% T# ]% D
- doubleleftD = 4.3, rightD = 4.3;
* Z6 m/ l$ O0 W' N: a9 ~
$ w3 r& V; f5 ^- publicvoid adjust() {2 M8 @; U% k: R1 F: N7 o
- //wait for release0 S e9 a) Y; z+ V4 Q: ~/ x
- while(Button.readButtons() > 0)
# z* l! u6 t0 B0 K3 a - ;
5 `: ?: S& ^0 a8 A0 _+ D' l8 ^9 F - while(Button.readButtons() == 0) {* r& z# L% @5 e2 g' [
- //input size by adjusting the wheels2 F1 j; m) {8 @; L5 f
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;9 [; x( j) `, D9 [- V# V' b
- leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值4 n: U4 Y: [8 ^; `% q% ?
- ) P( }) V/ A$ Z
- //display the size input
7 J8 k ^2 ]) w" E* D - LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
8 `8 ~, U; d# U$ u! `' A - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
. o% T1 d8 t; P% g - Delay.msDelay(100); h6 E* D, w w* @- j5 ^
- LCD.clear();+ G1 C( J0 a4 G e$ a( u
- }* M) G" s0 V/ ~/ I/ O3 U. Y t
- ' M9 m @" ]' X! V& Q9 }& F+ }- A7 o
- }
( i1 R6 y% d' N1 d# l
" S0 {( c; `, `* a" y0 q& o5 q; g- publicvoid go() {
, p& Z, E) ^4 q - //准备起步
: @' T' W; t5 K4 p - //wait for release
5 W3 R' c5 g. ]& S; c - while(Button.readButtons() > 0)
( n! V. m& y/ E - ;
) U2 z" }! P) I - System.out.println("pressto go");% [' M t( `& V4 q9 K
3 b0 A9 i( S) o% H% M' t( _0 [) l- Button.waitForAnyPress();; l3 P& Y c: h$ N: a
- LCD.clear();
' A9 l+ a, \0 I0 N, Q - + M2 u* Y5 m' m. z F" b$ L+ h
- //初始化
1 w( U5 F6 }5 K' ^6 ]5 { - pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);( ~) _8 U4 c$ v0 J5 `, \ ?* Z
- pilot.reset();
; Z9 \3 L6 H J: V - 8 @8 {2 U; b0 Y( O3 G
- Delay.msDelay(3000);
0 ~6 s/ l4 M0 b( O, x6 E8 N/ o1 J - 1 d, |: O) e2 ]: T
- doublespeed = 10;
. i: V, R# m) d1 O F, @. x% Y - doubledistance = 0;$ f+ @2 Z) o0 Y4 b( R ]
8 b/ A: u6 a' j" g: P$ r- //起步加速2 d* {& A! O" X
- pilot.travel(300,true);' H0 Z& `+ Z. w- M- K. V
: i5 F6 O( H- X3 [" V' c& r- while(distance < 20) {* ?$ Z7 ~6 u/ Z- s( ?
- distance= pilot.getMovement().getDistanceTraveled();
" ^- f, m% Z" t9 w4 b" } - speed= distance * 5 + 10;
' {& t- J. _. B! o( _ - pilot.setRotateSpeed(speed);
5 ?# _# _) o0 J - Delay.msDelay(100);
. m' x$ i( f# Q8 {( }, V* E6 v - }
8 G. q2 R& y4 c3 l+ w0 f - for(int i = 0; i < 10; i++) {
9 C7 V; t& @. T S E6 [ - speed+= 5;
7 U4 Q. K9 L9 K - pilot.setRotateSpeed(speed);. I) U& M6 l" a6 Z0 A% O
- Delay.msDelay(200);
' z; K3 N; W. D& l3 t* j8 Q! B6 P2 v - }# m3 E1 O' L9 e, [) z: e) s2 S
- : j, V+ p' M9 o
- //TODO 减速
4 P6 y s! q8 t6 K( H8 j# d+ D1 H - 6 K( K$ a: R+ o! m
- //停止机能' ?! ^& [; ?9 X, z9 m0 s/ C
- while(pilot.isMoving()) {, y- G" c0 n; m; G
- if(Button.readButtons() > 0)
7 F q" B. G# Q# M Y8 H% ? - pilot.stop();. ~ ~, R7 ]( a$ R0 H! A# A# u
- }
! ?: f1 O% c5 j$ u - 8 Z( p; K/ J5 @2 E+ L
- System.out.println("" + pilot.getMovement().getDistanceTraveled());
& p% E# O, D6 E6 A0 Y: M% ]* E - System.out.println(-Motor.A.getTachoCount());6 f% j: m4 U; {
- System.out.println(-Motor.B.getTachoCount());
1 [( c3 Q. w$ a - Button.waitForAnyPress();
1 z$ J" s6 H# Q - }: Z" l; A: t7 T0 ~4 a
- 3 [6 x) }6 \" d$ j2 q9 J& F* d
- publicstatic void main(String[] args) {
2 D3 f8 H/ k* z! S$ U% Z - Straighttraveler = new Straight();
6 U# g5 v# z0 Y; a" y/ l. ?
+ _# d8 W, Q- Y- traveler.adjust();4 P) I; z# P) ^, j1 q
- traveler.go();' T6 P) Y( ^2 R
- }3 d7 C. P$ H) B" {) x& ~# M
- }
复制代码 " m: O6 T) ?+ ~& J# ]" P
|