找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12197|回复: 7

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

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

& w* P0 y/ m# t9 {- B" r8 o! q) Y
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
" ?& \7 d% D" F. h, U$ h" N
场地8 I- P4 \2 d, G$ X3 z$ F
  水平度和光滑度
在家里当然瓷砖的效果是最好的! |! E# n, _% J8 d
  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直  Q; C1 K) {0 Y. _9 [
6 e: D& K; V$ v, ^
车子结构. G; {0 P; c" J# {4 @% ]
  轮子间距: d( O! _) d5 V6 F3 D
     轮子间距越大越好,稍微想一下便知
4 f- B# ?9 y' N0 U  轮子大小1 N* Z+ G" E# A' \
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
  R( R. ?" h' Z5 i0 F9 n  随动轮的设计5 J, J! R7 x6 n9 U3 q' M
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
; S% E$ T, p+ t& _3 r  重心位置
5 [5 X2 q' y; k+ n     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
# b/ d) Z  m( [$ S: x/ Y  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
  L; |( ], k1 F3 i1 m  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)6 d0 B" I0 Y& @0 q: c; R
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动. h; n. W0 `0 J0 G! C& L
6 B( |; [( S$ M0 \+ p1 k
控制程序. r& U0 {% z. e8 ~
  运动过程控制
  u0 _, _* L# g* i. f! X+ q     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
' X) t+ I" G+ s8 k; Q+ ^( i# F& F$ j
调试与运行5 A4 z% a# b. i* L  Q' s
  轮子转速调整(车轮大小的设定)
+ m6 @$ k/ y! f6 Z      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法- D: k6 S; O' p4 y* |2 D# q. I6 o
  起始位置车子正方向和直线间的夹角: N% B' v$ ?& K2 r5 H$ m1 {
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
2 g2 t& s8 |) J
& Y7 H& E8 }8 r" J. w2 t% J

- Z2 U: a9 K8 {0 h
然后上源代码:

  1. # ^; }6 J" }( w
  2. importlejos.robotics.navigation.DifferentialPilot;/ X9 O  J' X; k4 C4 J
  3. import lejos.util.Delay;! y3 U/ `6 Z. m9 F# R) r
  4. * x3 R$ d/ L7 t6 {; M# j
  5. /**
    ( W* ^, b* X1 W/ J" {9 L
  6. *Robot that stops if the buttons are presses before it completes its travel.
    0 B) K# O  Y% I5 J* U6 n
  7. */
    6 u2 p/ `+ T" w

  8. 8 y8 \, t) X5 T, t  h2 z  c

  9. 8 D3 Q" h! C  A
  10. public class Straight {
    0 ~) b' Q5 m# I3 ^  N! ]
  11.   DifferentialPilotpilot;
    $ Y' E5 x% X) o/ T/ h- h
  12.   doubleleftD = 4.3, rightD = 4.3;
    ) z1 O$ B6 i: `! b2 F9 C" L% g
  13. : T. M, G; t  [$ U
  14.   publicvoid adjust() {, c+ j. C( {! b. x4 ~5 P' e
  15.            //wait for release
    2 ]9 \# D. b5 e! J+ U1 E1 o% g
  16.            while(Button.readButtons() > 0)
    ) a$ [6 ^$ v' y
  17.                    ;
    3 h& [  q* U! V! ]  P
  18.            while(Button.readButtons() == 0) {+ D& [" G& i8 ?6 t% H, M. _
  19.                    //input size by adjusting the wheels
    . V+ V8 T" m7 n3 k1 c; d+ W
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    3 z* |& y! v; F5 o
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
    / Y8 U; |9 a: M

  22.   K+ e( D- B0 j
  23.                    //display the size input5 K4 Z4 ], F! ~
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);/ k, `( J5 Y6 m% m! z! p
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);2 k( \. X0 j; E7 T% {
  26.                    Delay.msDelay(100);( Z( X* w& S; n3 n# J! v" t8 N5 ?
  27.                    LCD.clear();
    ! i' E% F, Q2 f$ g; F
  28.            }
    6 v5 Y2 X* e% ^1 q! S" n( |

  29. - k& `$ ^: s/ A; d
  30.   }* _) }2 E/ N4 ]7 b) q+ U) b- z6 j

  31. + f5 Q9 G6 Y2 M! ?" D) h  T' m4 o& M
  32.   publicvoid go() {* z5 v  h! i/ Q0 P8 {  j5 e! B
  33.            //准备起步4 W7 d% n( J& n, m) d
  34.            //wait for release
    ) |1 V$ B4 `9 T: |
  35.            while(Button.readButtons() > 0)8 M& ?2 M6 a% d4 T
  36.                    ;
    $ [& Q" V0 z* L3 i# K3 V
  37.            System.out.println("pressto go");
    . Q- u2 z. b% I: W2 Y% C% F

  38. ; h: ^( B, R% }$ M% n
  39.            Button.waitForAnyPress();; C" O, m6 s6 R3 X1 x7 z
  40.            LCD.clear();
    4 H5 x- Q* L5 X6 C. w
  41. : \  t4 k6 n9 n  `: C' d
  42.            //初始化7 C# O! ^% \0 V, W8 x2 T9 N- a3 p2 K
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);% z* D  D* Y2 K5 c- p2 m9 @: j% z
  44.            pilot.reset();
    5 f* d8 t/ M' C  U: `
  45. , @2 t; H  ?$ \6 R" G
  46.            Delay.msDelay(3000);. B) [, z, k, W; ^! |( e
  47. - `$ T! x2 ~3 R' d/ G4 p0 y
  48.            doublespeed = 10;
    / K$ f3 j" {8 f9 r
  49.            doubledistance = 0;
    9 V4 U5 w' J9 p& k, ]' r

  50. % ?( n  G, Z7 [, j9 o3 g9 C- C
  51.            //起步加速
    1 Z" k/ \) A, Q- B4 z8 v
  52.            pilot.travel(300,true);9 ]$ w* T' K! r& _7 k" ~
  53. 8 D  `3 _9 o: y7 U
  54.            while(distance < 20) {$ c0 ]0 X" b, Z6 P; K' i5 j! J
  55.                    distance= pilot.getMovement().getDistanceTraveled();8 u4 j! U1 }2 q
  56.                    speed= distance * 5 + 10;2 n" {& N2 h7 c/ l0 l
  57.                    pilot.setRotateSpeed(speed);: E* B) R. ?5 B) N; G
  58.                    Delay.msDelay(100);
    % J/ n  e7 z/ Y  g% g
  59.            }) o& W* X. q3 j! K
  60.            for(int i = 0; i < 10; i++) {, E2 M% Q2 e, n2 T( l
  61.                    speed+= 5;/ I( P2 l7 I) \; L" \; Q1 H. o
  62.                    pilot.setRotateSpeed(speed);
    + t4 C2 }& z! m; N! O: B
  63.                    Delay.msDelay(200);
    3 h# h6 l9 W! f6 U
  64.            }3 q# [3 G" S8 `$ J; \/ P

  65. ' b  G/ `+ y, ^/ b4 n$ o
  66.            //TODO 减速
    3 C) c* Z+ X) j

  67. 9 Q! B8 j9 J* n7 z
  68.            //停止机能
    , D/ k7 V: k2 j
  69.            while(pilot.isMoving()) {
    * P6 V& P8 J4 W
  70.                    if(Button.readButtons() > 0)
    . r! X$ k5 P! Y" A2 A/ d) \
  71.                            pilot.stop();
    5 E0 Y9 ?$ N- d: {! P/ O; j. i
  72.            }- F7 }9 e3 V; x- L9 h$ f

  73. 0 d; E# R8 O7 d' N% ]$ \
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    - v# r1 \, z8 @' p* |
  75.            System.out.println(-Motor.A.getTachoCount());
    7 x! W/ _, \: h; f1 R* D
  76.            System.out.println(-Motor.B.getTachoCount());" U& |! f$ U) M8 b4 V  h- \
  77.            Button.waitForAnyPress();# F8 n% |. r8 K: h6 {
  78.   }% ?$ L7 D, r9 G( l

  79. 7 C& S" J! _9 Z$ g
  80.   publicstatic void main(String[] args) {/ [0 R2 S9 Z5 T3 O2 ~$ ^7 J
  81.            Straighttraveler = new Straight();9 J) Z( z+ q/ f* O+ }

  82. ' |/ \6 q( q% I: s# c/ _
  83.            traveler.adjust();, Z( ?; I: h# _7 r0 t4 h+ @& \: F
  84.            traveler.go();" t4 t) S& g4 r# B
  85.   }6 ]! D' Q9 C. h
  86. }
复制代码

3 y+ V* ~% y! ~% U' y
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 编辑 2 e; W2 ?, l0 e. g% Y$ b- ^* W1 n
5 n. Z7 ?) e/ a- ~) ]& I
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:220 E7 ?4 ?* J9 @* P! c5 b. G
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

9 Y8 T' G9 a! u  r我用的是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-6-2 20:25 , Processed in 0.404213 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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