本帖最后由 hello怪 于 2017-7-25 22:24 编辑 4 Z; ]7 D+ r9 P) i
$ ^9 N. h# M% Q0 ]% X! f
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址: http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html 3 ]6 v) o6 a& q6 S. k
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
4 ~6 _4 D) W! A, a场地- P9 N$ i8 W: o9 M' T* P
水平度和光滑度
在家里当然瓷砖的效果是最好的' n$ p% L6 N0 F
线的直度 虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直# i- X: n0 ~, ~& T5 w
3 d0 L! M1 @ h+ J
车子结构9 `$ B n7 W8 y1 z$ d4 d. P
轮子间距
: Z) \$ e# s& o1 q) |5 r 轮子间距越大越好,稍微想一下便知- ?' ?' E! {9 d/ C- L# q
轮子大小
* g$ c- E- H! ]0 Y. R) y! X 轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)7 y+ W$ @+ F9 J* s
随动轮的设计
, f# p, @5 J6 E6 n5 S 随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
5 b+ `8 \; l6 ?% d; I" Q 重心位置 J' l# S" U8 d# P
重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
2 t/ g8 z& Z5 h+ j9 D1 ~) h& A, { 结构稳定性 不用说,肯定是越结实越好。但是不能造成重量过大( j b! ^8 K$ w* Z7 ?0 h# f2 H
轮子个数 有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
3 f' L5 Q- c1 K: h3 m 驱动方式 这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
. @6 f; K/ A( Z* L0 V/ w
* R. y7 x2 J; X, m& o" s3 m控制程序
* M- F; r. @' N$ Y$ j- W& Z 运动过程控制
' R, ]7 F3 Q8 ?' v4 E 好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)4 x( n# Z" [/ h+ k
( F/ v+ T- M. P( ]* W( v调试与运行
! V' _+ J" [. [+ k, z: b j3 ~ 轮子转速调整(车轮大小的设定)
/ A! }9 Y' s5 q+ A 这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法+ `( H) f5 }0 A) ^
起始位置车子正方向和直线间的夹角
* z' `$ h3 [7 b! |* l 一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点 ; P- s' ^5 W! @, w
* b$ H3 W7 p) x8 s$ i3 N, N
/ x$ M0 Y4 t; w1 D8 }7 c
然后上源代码: - - l/ @ O; G; j& I
- importlejos.robotics.navigation.DifferentialPilot;' i; c6 A4 Z% M& q9 q; z- t
- import lejos.util.Delay;
2 r; T8 Y4 h% G% X3 a
$ J+ E/ B% x2 J# M' M: f- /**
7 z$ H) Z2 v2 a1 _( t; N/ e - *Robot that stops if the buttons are presses before it completes its travel.4 k5 h) ^# t% ]- }
- *// V# G$ @( m: c( h+ Q2 q J* E* n+ u# D
5 U4 ~! @; b, A6 @& l% z6 ]- 0 i& o6 b3 L1 {! p! _5 m
- public class Straight {
) o; O% n6 r% N% } - DifferentialPilotpilot;6 t$ y- @1 c6 u, F
- doubleleftD = 4.3, rightD = 4.3;
7 C; Q) v' {4 N8 d( _2 ] - # X3 x& P8 w+ @& P4 I7 J/ L, ^- w
- publicvoid adjust() {
; V4 q4 f" [4 S$ \/ p - //wait for release, J3 F7 v3 o. b$ B, ?0 g6 @
- while(Button.readButtons() > 0)
1 x! ]0 T0 j: F9 l3 ^2 R+ c - ;) N9 X! C+ [% Y
- while(Button.readButtons() == 0) {1 S: y% y' u1 i' H% Y- @3 d: c
- //input size by adjusting the wheels3 ]3 ^4 ^6 p& K% q. T
- rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
" O. {! L% }7 o) @/ g - leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值) P q4 r+ \% J# ?
- / [+ g) I) ?+ h z) V
- //display the size input1 X) ~* U$ K6 C6 w; Q3 e w
- LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
4 f. @) m- a% Q+ s w - LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
9 o( ]% l/ Z4 g& T2 V4 t5 |: F - Delay.msDelay(100);( ]$ Z6 Q8 h- z
- LCD.clear();: A2 e& c0 y3 ~
- }4 }6 ~* l; D5 y1 n0 B: U8 ?2 }
- 1 b* Y- y2 b+ t& X' ^
- }
% z- q5 R" K, w/ h* E
" X" l( D4 q$ ?" ?: g" _6 a- publicvoid go() {$ u, ^7 ]7 T" M$ {
- //准备起步0 A% E% I# Y* L7 q3 d
- //wait for release
; z, h+ d7 o; u2 h - while(Button.readButtons() > 0); m( U* g3 j3 e# {+ L6 C( ^
- ;
2 T+ ?% R. Q$ y0 t; W7 m - System.out.println("pressto go");. {( z0 h" _+ r% P4 ?
- & w# H3 K% P" _0 M# U5 N( ]$ R# D
- Button.waitForAnyPress();1 a! {# S# D: I
- LCD.clear();4 n$ u; z& l3 E
- 0 n2 q8 D# y. Z; b+ n& y
- //初始化' a& X ^* B6 S, L
- pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
' t5 D; d2 o8 [' Q0 p o; ` - pilot.reset();
% d, s0 H5 e7 d, W# Q! F
+ r3 i0 r: ~" ~& h! a+ }- Delay.msDelay(3000);
# x' V0 {( y. u. }4 G' A - * ]5 q' A# S7 u y$ j
- doublespeed = 10;4 \ x* W1 l) y; _! h3 h8 i
- doubledistance = 0;
3 w" M6 W8 n$ | - " v. c6 p, N1 M( j! y
- //起步加速) J4 b# H7 A. |$ X5 q1 c B: r
- pilot.travel(300,true);
1 [1 |# y3 K& g
' i; _3 f+ x( W1 Z& d( f- while(distance < 20) {
+ u* @& H' C" ~ - distance= pilot.getMovement().getDistanceTraveled();
8 C$ D- E! z/ n- { - speed= distance * 5 + 10;
: N1 S0 `* P) w3 C0 l+ x+ R9 ^ - pilot.setRotateSpeed(speed);# x; G( C0 v. _, ^
- Delay.msDelay(100);
2 M! _5 O# b+ ]" C Q; K - }
& F2 [0 |, l. I* D - for(int i = 0; i < 10; i++) {
; ]5 G7 B# t) j8 ^5 E! q% c - speed+= 5;2 Z/ u- F/ z; ]6 K5 p- ?
- pilot.setRotateSpeed(speed);& M! o1 _5 d6 n" f
- Delay.msDelay(200);
! h: ^. L6 `' i8 l" o7 q. I - }. U9 v! X+ ^0 n0 p6 X' G! O
: q9 \2 ~9 |+ O- //TODO 减速' L* n: X j+ f( R! O
- 1 [, W O4 ^% K3 ~ _& _, Q9 r
- //停止机能 B" r8 G1 X$ M g) J2 O0 S1 t
- while(pilot.isMoving()) {3 A N$ D8 I' Z2 w9 d0 Y- @
- if(Button.readButtons() > 0)5 i, [* @; h* n* a, s' l+ F
- pilot.stop();$ D" o+ i. \5 }. {+ G' z! h( H0 e
- }
4 }2 w% {1 k# B$ \9 S3 u3 m# T$ h
* E0 o, M9 w! t8 M" {8 b S- System.out.println("" + pilot.getMovement().getDistanceTraveled());7 ]) K K+ B \- {/ W3 Y
- System.out.println(-Motor.A.getTachoCount());
' Q( I& z# D+ m, [5 z - System.out.println(-Motor.B.getTachoCount());$ c: g4 l5 R, [' n5 \ R
- Button.waitForAnyPress();
1 |/ c2 M5 E# ~' y) `3 x2 z - }3 N" Y `* X9 D% s1 u* [9 N
1 [- s( L) O1 g% [- publicstatic void main(String[] args) {! g" W* [7 ?1 J5 t. W# R
- Straighttraveler = new Straight();
; a& d! N; f' T: t0 [# `" b - ( a# R# E7 O' ?0 Q+ R* y# i3 B
- traveler.adjust();) ~, e! J2 H: s8 t
- traveler.go();
5 Y7 b) R) ~) v' ^, ] - }
- g; ]: o y: B) s/ E - }
复制代码
" ]. V" U4 S$ K; J% R7 Y* `/ s |