找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12818|回复: 7

最直的三百厘米——开环控制的小车

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
. y! g% T( L2 i+ j4 F. u
" m9 Y7 r% k% f* P; s  z
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

4 T5 O8 h  h- Y/ I) |" S5 N# z3 s
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

& w  v' s% i) v
场地
1 Y2 u; ]' g' S& U, x  水平度和光滑度
在家里当然瓷砖的效果是最好的
  Z# s: ^) u& Y; A# W3 B$ h  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直# h, g7 f' }) B, P  C

8 n) @; D  c. P+ f" S$ S车子结构/ M! J# ^# w. \/ b/ F6 i3 h
  轮子间距2 r* E  G. x% W4 m" d/ L  t9 E  c5 Z6 ]
     轮子间距越大越好,稍微想一下便知( ]# }' j, c: r0 Q
  轮子大小  e! [8 ~/ q2 `7 ?
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)0 q' X9 X* l3 r9 m
  随动轮的设计
9 X, ]2 o. C2 n3 I3 K& N& a/ Y8 D     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
4 Y  W5 L+ Y2 l  l  B0 @% D  重心位置
& {! q  J# \6 O. H* ?     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
  U9 G9 {7 h+ R# g$ V  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大* v8 o! J- D! d
  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
& S  U. z" w- ~& p5 g  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
7 t9 ~; S0 G+ G% T1 I2 ^8 g1 D' N3 p; Y+ Q1 p
控制程序7 f5 Z% J* B  f, f3 `% N
  运动过程控制9 G) `( w* N7 B
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)3 t9 U2 U6 @9 o1 K

9 w( t6 L  _  Q" Q0 O, U调试与运行/ f# p! e: `* p8 ^8 u- d
  轮子转速调整(车轮大小的设定)
9 D9 s/ e8 D4 G1 ^+ j5 C      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
# ^# I% l1 v' M; P' ^& U2 g  起始位置车子正方向和直线间的夹角6 J$ t1 @5 o  P/ P' D3 [6 R" P
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
* {6 |9 {( {  e6 D3 R" Z; q  y
9 t4 U0 X+ {* x& l  G( R6 d: g

+ @* a6 ?' J" Q; t
然后上源代码:

  1. $ A9 r0 n, \9 F# H
  2. importlejos.robotics.navigation.DifferentialPilot;
    0 l! U  W# N  j) B# v: a5 O( T
  3. import lejos.util.Delay;
    : Y4 G- q+ r8 ^/ M

  4. & }1 P* Y9 D! Z* ~0 \! L" {; G
  5. /**- J4 [5 d3 j9 e; e4 T* A
  6. *Robot that stops if the buttons are presses before it completes its travel.
    3 K1 v. u0 z6 x
  7. */
    , ~2 P( H0 y3 }4 ~/ M% i- y/ @
  8. 8 H) b, ^4 x4 W- s

  9. # V! n: M5 `& K
  10. public class Straight {
    1 s( |0 G  y6 l; ], m' f: @1 W
  11.   DifferentialPilotpilot;" q3 s+ k- K+ X, F
  12.   doubleleftD = 4.3, rightD = 4.3;
    3 H8 h* y/ E- a! U
  13. 8 n. O5 \6 B1 w+ N2 k+ q9 t
  14.   publicvoid adjust() {2 i' E& ^1 Z' e: d" `3 q  G! `
  15.            //wait for release
    1 d1 M7 q, f! X5 F+ A$ V% `1 j
  16.            while(Button.readButtons() > 0)2 M* V+ \! y) r% c+ ~7 c
  17.                    ;
    ' N6 ^! W# B* p
  18.            while(Button.readButtons() == 0) {
    ; Q# A2 |  B9 A( r3 O0 x* K( F
  19.                    //input size by adjusting the wheels! ^. X3 t+ P( ]) X( ~
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    / e- k$ |, z- s0 s; y
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
    : y1 D# q" v# H  h
  22. 9 y! w5 ^4 Z& J2 p
  23.                    //display the size input
    2 u/ y+ a% i" a  c2 U
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    ! b2 D0 ?/ F5 i7 o( g
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    2 m  @2 V; d1 S
  26.                    Delay.msDelay(100);3 ]4 g. m# H6 j  q
  27.                    LCD.clear();
    / Z8 ^' \: B3 H3 D3 t0 I
  28.            }
    . }) @8 C1 k7 m' j, a. ~( e  [# x
  29. 6 n) O0 n! T# a5 E7 J# K. s
  30.   }+ a; J, p8 @8 g" X! z

  31. + Z$ t% R. W5 G
  32.   publicvoid go() {* T, n5 D- s% _( T* r8 T% ?. Q
  33.            //准备起步
    % S" q$ x( ~: R% Q
  34.            //wait for release
    ) I& U, i0 B, N6 p: H) W7 w) ?
  35.            while(Button.readButtons() > 0)
    5 `) ~" n  r6 F( K: S0 K
  36.                    ;9 Z% N! Z" @7 m0 {  T( B
  37.            System.out.println("pressto go");
    ' p7 E  Y6 r& u0 @# Z2 F
  38. 5 d- b/ T( J" q. }4 m# }
  39.            Button.waitForAnyPress();% @# ?( i* s) ^" [: x2 @- o
  40.            LCD.clear();
    . ]5 M1 t8 D; H/ N. R
  41. 5 K8 v6 d# e9 l7 E8 v
  42.            //初始化4 \! h0 m8 P8 D+ L3 K
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);1 R0 v! K- V- |* \
  44.            pilot.reset();% X0 |8 Q4 h2 n4 u0 V! U. ]+ f

  45. 7 I0 b) f: y3 n  ^
  46.            Delay.msDelay(3000);8 Z: N' w7 ]2 o. [2 ~) I4 U

  47. ; y9 [$ F. I" l1 H* q6 H0 p
  48.            doublespeed = 10;
    & [# S) x4 ~2 z1 o
  49.            doubledistance = 0;6 i% c% M) s3 h4 Z7 o
  50. / n$ s* ?1 t5 \& n" @0 t0 h
  51.            //起步加速4 N0 S9 Y" ?1 h
  52.            pilot.travel(300,true);4 s0 y4 ]1 ]/ z0 k: A5 A* {
  53. 2 O9 l3 ]  _3 t" `
  54.            while(distance < 20) {! \1 P; l. S5 L
  55.                    distance= pilot.getMovement().getDistanceTraveled();: q2 P( }9 w9 d' m$ I& @
  56.                    speed= distance * 5 + 10;' K5 x& V7 d0 U$ [
  57.                    pilot.setRotateSpeed(speed);: l! V2 |. f5 V9 c+ t
  58.                    Delay.msDelay(100);
      k6 y" C: W& I* g# o- {
  59.            }
    ( a$ @4 ^% `" E( M! G: q
  60.            for(int i = 0; i < 10; i++) {
    1 y6 R+ ~. ?: I% s
  61.                    speed+= 5;9 ~& U+ c' @; C0 @* N! e
  62.                    pilot.setRotateSpeed(speed);
    3 H+ K1 X  k8 l5 }, d
  63.                    Delay.msDelay(200);
    : n% m/ N1 W. b. j
  64.            }
    9 X, N! \- }, N0 x

  65. 7 n0 S; @3 @! |
  66.            //TODO 减速' T: C* u" p% _( y- u% a8 C

  67. ' }2 ^/ N& \: _: M* P# r
  68.            //停止机能
    & X5 z% o' r6 z& _: }/ U: a
  69.            while(pilot.isMoving()) {! O( [3 q4 z3 A. Z
  70.                    if(Button.readButtons() > 0)* p* }, h/ ]  Y8 S, W( b
  71.                            pilot.stop();( ~7 |' U' H9 ~& S" b) F! L
  72.            }
    6 X- a' {  U- y- D. J8 l9 s

  73. 6 M' {6 f1 G3 v4 \  o0 a/ Z' Z
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());, g2 t; q. M# o; W% o
  75.            System.out.println(-Motor.A.getTachoCount());
    ( x9 X) @$ h2 p+ O5 X! J
  76.            System.out.println(-Motor.B.getTachoCount());3 V" w/ x5 g( Z% Y5 j9 `
  77.            Button.waitForAnyPress();
    + g* I, i) A) \- [+ V' o! E
  78.   }; L. e  u1 S. P' Z" E! J

  79. # i8 T) N4 R. M/ O) Z
  80.   publicstatic void main(String[] args) {$ {/ D9 R7 Z% g5 g% M
  81.            Straighttraveler = new Straight();2 h* j0 l4 G) T
  82. : ?6 `: t% H5 Z3 f
  83.            traveler.adjust();
    ) I5 {% z. V) X6 j4 S# u
  84.            traveler.go();
    ( a1 k4 p$ s' j
  85.   }' `+ o7 y- K8 K8 ?% p/ f0 E
  86. }
复制代码
: v5 [1 I" w1 g9 N9 E9 V
IMG_20170720_111026()().jpg
IMG_20170720_114534()().jpg

轮子外缘与标尺间的距离:半个乐高单位

轮子外缘与标尺间的距离:半个乐高单位
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2017-7-25 22:10:06 | 显示全部楼层
二楼自占备用,欢迎发表评论
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2017-7-26 01:34:48 | 显示全部楼层
这个源代码是什么语言呀
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2017-7-26 07:22:29 | 显示全部楼层
本帖最后由 clx 于 2017-7-26 07:26 编辑 $ l/ ?3 s( V- l# ^% c
( F% }1 q+ `3 B& v5 E6 G! |
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
. ^" H5 @! N! u6 D# i这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...
( F8 k  C: X, b3 m7 a7 J2 q) }
我用的是lejos,一种基于Java的nxt专用语言。论严谨的话,程序结构的严谨和语言选择是无关的,但是不同的语言确实各有专长。比如这个lejos,他的函数库就比G大若干倍,有很多别人写过的东西可以直接拿来用。虽然G很适合给小朋友和初学者普及(本来就是针对于此),但是图形编程界面本身不适合大项目的编写,如果想要深入玩乐高的话转向代码是必然的
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2017-7-26 10:23:44 | 显示全部楼层
学习了,在乐高深入了解方向还不太明确,转代码确实必不可少
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2017-7-29 16:34:41 | 显示全部楼层
车子结构很好,赞
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2019-8-16 14:40:13 | 显示全部楼层
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2026-8-20 23:07 , Processed in 0.337475 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表