找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 13221|回复: 7

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

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

* n  D; y. P2 Z6 ^/ R! ]) i
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

1 w5 w$ y: x5 T+ `
场地# u9 h# M, M) J$ z4 b- j
  水平度和光滑度
在家里当然瓷砖的效果是最好的
9 F- x! J) u7 |$ v  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
1 a1 I5 J0 E8 _& }- E+ H2 D) a7 e* P8 p% D4 g: k: T
车子结构; @& n3 x4 |! ~) P& q0 z. `
  轮子间距
- f: n7 `& @' p- x) J* C- h9 |     轮子间距越大越好,稍微想一下便知
/ `& t* `" r8 F9 {  轮子大小, X, {! v- H. b  W7 l( t
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)0 m+ }+ `/ L' x
  随动轮的设计2 D  F3 H" t" |# d- W8 Z
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响. y  e0 m# _, y+ T( g% D' f2 }  i
  重心位置8 Y3 z% l" y$ o. v6 l; h
     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小% W6 Z, k1 O) ~0 N. `) u( ]9 L+ y
  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
, f7 Y9 C# F. U3 ]8 s  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。); [. r% d6 B  W: p! z" N+ S8 H
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动- o$ T- Q, G  z! n8 b
& {- k" z8 ^- c& }
控制程序: I  W) G6 l/ M
  运动过程控制- @& A' z2 D7 Y1 y3 D5 l/ t
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)  u) W. h% e7 ?0 v8 h( k3 @

/ C. E  x/ R8 [, {* K5 H! a3 @) Y调试与运行
1 Q4 e: x2 f, g( x9 G- U- x2 }  轮子转速调整(车轮大小的设定)
* `" z7 a/ k$ d7 _" \2 w7 e8 }      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
* ?6 }0 f9 I! y8 F0 ]2 ~7 e4 R; O  起始位置车子正方向和直线间的夹角- {5 `4 l" r& k* c
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点

0 e* Z; m, H! U, I) T" W6 j
' h5 r8 ^  w* {
/ t9 ~7 {2 q: [& i  i3 `$ Z* r
然后上源代码:

  1. " O: i, B2 z; e
  2. importlejos.robotics.navigation.DifferentialPilot;
    5 r5 E) @: s& K! k; p7 I- ^7 d
  3. import lejos.util.Delay;0 \2 ]3 L' }1 J

  4. 9 P/ `% d9 S8 c4 [7 t8 _3 G1 b
  5. /**
    4 j9 n* u! d2 K4 p
  6. *Robot that stops if the buttons are presses before it completes its travel.
    0 z5 g# k( ^. M4 C: W
  7. */
    / \0 s0 t% I0 v/ ^: L( Y

  8. ) U& p8 R3 g0 P5 c

  9. * T/ O% _  T: M
  10. public class Straight {
    - p1 X/ U- d7 w; a" t1 h; J
  11.   DifferentialPilotpilot;# D* l( b3 `( M
  12.   doubleleftD = 4.3, rightD = 4.3;- i( x2 g1 w1 O; U" Y3 ~

  13. # R/ U7 C% N! `) x( H
  14.   publicvoid adjust() {
    * Q8 L5 x0 ^  w
  15.            //wait for release1 I' f7 `7 K! I: P8 I
  16.            while(Button.readButtons() > 0)
    # \/ Z# T1 T5 ^* `
  17.                    ;& ]  H+ ]3 R; R; p2 M/ V
  18.            while(Button.readButtons() == 0) {
    ' X" ]- H( ?# W& C/ E9 w5 ?; s
  19.                    //input size by adjusting the wheels# {3 C# ~# G, |! z( J
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;/ _. b) K% S( j7 t' G- j8 d: c+ Z
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值( x# x: H8 n) n9 I5 q
  22. 0 l2 R6 o% c! J3 n, _/ j
  23.                    //display the size input. D2 l1 n$ N2 t% |5 ~9 V
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    6 S5 [5 C! F: m3 J# A& t
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);" ?4 e0 A( Z3 _# x
  26.                    Delay.msDelay(100);
    5 @! T7 J( {$ H2 P, n8 c' ^  h
  27.                    LCD.clear();
    5 d/ \/ A) N( b  {. E2 t# N: X
  28.            }! J5 N( @# [& l8 {, f) m' z
  29. 2 B% I' z$ g- f9 H: p
  30.   }. d* \/ P2 f% P* ]: s- Q/ G( s+ e

  31. % j- K$ e* ?: L& C
  32.   publicvoid go() {
    * P& ]: L3 W6 a+ d' k9 z8 y
  33.            //准备起步
    ! _  E* U* J5 @* S1 g1 K- [5 h
  34.            //wait for release7 c* V- e4 @& h# f- S4 p
  35.            while(Button.readButtons() > 0)* O. E! F; Z0 W$ P6 c) j9 t0 a
  36.                    ;
    . }5 Z& v/ L2 f+ `
  37.            System.out.println("pressto go");
    ; x2 w0 S+ n" M' p. R9 G. }8 R  p

  38. % p5 T- P5 \) j5 _8 G* E
  39.            Button.waitForAnyPress();+ g* D  ^' k0 a/ @
  40.            LCD.clear();8 @, M* F0 _  ~8 A2 k1 t- \
  41. ; E0 S) Z8 W# N7 f  X" J  ?
  42.            //初始化3 Q( Y5 m( q, l9 |; a( ^1 U
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
    " E0 k9 L$ v6 `" m
  44.            pilot.reset();3 h2 x  ]0 x8 s7 F6 h/ {" y
  45. : ?9 `9 D: j) s; w* }* ]8 y
  46.            Delay.msDelay(3000);
    7 I8 A7 u* h8 P  [/ {) H' j1 c
  47. * A! Y3 O1 f7 y/ L3 _
  48.            doublespeed = 10;
    " V3 F. X/ \. r1 V% {! q
  49.            doubledistance = 0;
    * N9 C# T% ?! X& W! G0 D/ q

  50. ) b& C1 F5 g. {& N/ t/ y7 J/ D
  51.            //起步加速/ R8 y/ j% ^1 T. `4 F+ A
  52.            pilot.travel(300,true);
    7 {0 w, h1 ^0 F: ^" @! n) @

  53.   M! a$ ?' o- a! }+ Z# T
  54.            while(distance < 20) {
    6 ?' {+ ^% v, p5 ]6 l
  55.                    distance= pilot.getMovement().getDistanceTraveled();
    ) e7 m, |; S$ P- K, Q6 B
  56.                    speed= distance * 5 + 10;2 ~& D+ [* D8 u' H8 p- z  N
  57.                    pilot.setRotateSpeed(speed);6 [- \( I- w" \6 u; F5 e8 p9 Z) b
  58.                    Delay.msDelay(100);
    1 H! _; {0 E, p* U
  59.            }; x) H* s6 T0 }& ~+ S1 [5 l8 K# C6 M
  60.            for(int i = 0; i < 10; i++) {; A+ o) W0 }2 q7 e
  61.                    speed+= 5;9 M" [9 @* B+ v1 b
  62.                    pilot.setRotateSpeed(speed);3 w$ t4 m$ T) V8 G
  63.                    Delay.msDelay(200);
    ; m. m% L& }: @$ {9 Q3 H* u5 I) p
  64.            }0 \/ a; W8 c; B- d+ A/ Y

  65. % k  o, l" f$ {- t1 R
  66.            //TODO 减速
    - q. F$ k1 h. d
  67. 3 }- U6 H5 G7 \
  68.            //停止机能
    $ Z$ L/ t, z  y* }' T7 c# r+ B
  69.            while(pilot.isMoving()) {
      B8 S# a0 r0 a4 a
  70.                    if(Button.readButtons() > 0)
    3 L. ], K: [, C9 q! u
  71.                            pilot.stop();* i+ u- F, i" F  N" k# R6 q% Y
  72.            }1 B# o) X  ]4 ^/ p

  73. $ B2 N7 Y$ F! {
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    ( ^5 H3 }" Q# P4 a9 K
  75.            System.out.println(-Motor.A.getTachoCount());7 ^; z. `9 ~% `8 Q! C3 |
  76.            System.out.println(-Motor.B.getTachoCount());
    5 `5 R- g# G: q7 i: w- l; [
  77.            Button.waitForAnyPress();
    " `7 j3 R0 ?9 |: X7 o
  78.   }
    , \: [6 b3 f/ Y+ H
  79. , L9 c! X9 [3 v8 V
  80.   publicstatic void main(String[] args) {1 m* q3 H: _9 x) k4 i
  81.            Straighttraveler = new Straight();* {2 b! l8 z. u( N) p4 g

  82. - p% R* Q; ^- M! ?
  83.            traveler.adjust();
    . L1 r3 b* p0 z! z; E
  84.            traveler.go();
    - z8 q, Q8 H* E' s
  85.   }
    8 ~( H8 j- J5 W5 ~0 M" X- [
  86. }
复制代码

$ |6 `( c2 U6 \
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 编辑 # a, r9 a! U6 [  K! B  d
$ K- ~5 u7 b/ p5 L3 m
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复 赞 踩

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
% ?4 c  }3 `4 W. \# N2 `% t1 j这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

! f9 z5 y. I* F2 i% g2 _4 I我用的是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-10-10 11:50 , Processed in 0.123286 second(s), 20 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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