找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12516|回复: 7

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

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

- @) B: _2 n9 m8 }/ U8 ^
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

# G+ s1 g% u  O+ f) }  v* |
场地
3 l, b# [# g) J! B6 p( J  水平度和光滑度
在家里当然瓷砖的效果是最好的
! G8 d5 i  R6 X  [. m  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直/ k* v7 s1 ^/ P" G& A5 ?# [. v& V
$ _; J' A0 c, H' N1 Y, L
车子结构: p2 y& H0 r# g- b9 h: `. s
  轮子间距; x3 ^4 ]" }; |7 L3 _  g
     轮子间距越大越好,稍微想一下便知
! b) l% r- w4 ~4 `- b  轮子大小" [3 Q; c1 J6 G, a: g
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
& Y" _$ H8 x8 S( Q7 O) X  随动轮的设计
* V* M9 k) d) X     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
/ A& t/ G$ i, R. @# b& `4 Q6 E( i; {  重心位置9 N+ ~1 g2 }7 ]' C5 W2 f4 Z# n6 E
     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小  T" }3 w1 m( A7 o
  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大) _& a8 V+ X5 \0 V
  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
  _  Q; T, P# g" N# b& N  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
- A& M) B' x0 i; o- J7 U
2 b9 E4 r1 ]- U控制程序$ n' _( m4 {( K% q
  运动过程控制5 K4 X' \$ j4 k) F6 @
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
9 j+ p* F% C* i! ?* q( B; N$ G; N, |( P4 F9 t% d# |% }/ F
调试与运行+ w/ V6 u: c% K" n' K: j
  轮子转速调整(车轮大小的设定)
, R( f) R! H- Y" y      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法; S: V) w5 n' W! k' h9 ^
  起始位置车子正方向和直线间的夹角& ]+ S7 }6 U9 O' \, z8 z
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
+ n0 F2 s9 {. q

4 |# v# v5 U9 f6 x5 Q. Y! v& l: D) y' U/ k1 {1 I2 H$ N! O, X# h* b3 r
然后上源代码:

  1. 7 K+ a1 X/ g7 B/ I, \
  2. importlejos.robotics.navigation.DifferentialPilot;7 o, F, w3 B5 \7 y
  3. import lejos.util.Delay;
    * e& n) l+ ?- F% D1 O- _. w. l: z8 M
  4. " k: h% T( b; f+ I& n5 V2 h4 U
  5. /**
    5 S1 k& @+ S) Q8 d
  6. *Robot that stops if the buttons are presses before it completes its travel.
    - U. z4 r" q3 K6 f8 o# m9 c
  7. */
    ' {' ^6 l2 `* z0 X

  8. + u& |6 k% n  S2 e  s
  9. # B  K1 p* V, A* O% x3 G( ]' w
  10. public class Straight {* ?/ K* v8 l5 r
  11.   DifferentialPilotpilot;; u  A7 S- D+ ^0 [/ M9 v( }( U( }
  12.   doubleleftD = 4.3, rightD = 4.3;
    5 G3 @+ Q7 V# X0 m: N8 ^" I/ \
  13.   o- N) r) y# k9 O4 }7 E
  14.   publicvoid adjust() {
    # h3 D' h2 u/ {+ N, v2 M
  15.            //wait for release
    % ?5 x+ _7 z3 R! g- H4 x3 K
  16.            while(Button.readButtons() > 0)
    7 ]6 Z  y: `& Y0 a
  17.                    ;
    0 v3 S  Y0 h% f( l# x7 t! p
  18.            while(Button.readButtons() == 0) {
    8 W2 M, ^) S! e4 V: C
  19.                    //input size by adjusting the wheels
    , D) l/ M6 @7 K, M  |5 Y  Z9 r
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    1 m( m0 U  H" H/ K
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值& P  b: Y, W4 T  U) L- A! J

  22. 6 f1 z* y2 z/ V' R  t" _0 l* C! l) `
  23.                    //display the size input
    ; e. D8 {# h! j; w; V
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    0 h6 f( ^# ?- F7 w( w
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    2 f, }" x5 Z* _1 j9 n+ s
  26.                    Delay.msDelay(100);3 |' y$ R3 H7 A7 `  O1 o& u  Z
  27.                    LCD.clear();
      \) @  q4 j0 S1 K7 z+ e
  28.            }
    ! D0 r: Z1 U' y" r$ |

  29. % I* ^( r8 a0 |1 q, w
  30.   }4 h; _" A% o- r7 k  B* v& O  p* i5 f

  31. # S9 ~& p! ~  B. Z5 }$ F) B
  32.   publicvoid go() {
    ; C/ b% W  u, u
  33.            //准备起步
    " `, V% g4 z! O. c' R2 c. V8 N
  34.            //wait for release
    & J; d% E' h: g7 k; @+ _
  35.            while(Button.readButtons() > 0)
    , a& x+ ~) N; Y4 b$ u' K5 d/ V- z& j
  36.                    ;
    5 Q8 J1 G$ x* p( ?1 o5 j, |
  37.            System.out.println("pressto go");
    9 f" g- g; d' L1 Z. d# p# b
  38. + ^, I' _7 g+ h) k5 ~
  39.            Button.waitForAnyPress();
    9 o; x7 j" v3 d
  40.            LCD.clear();: T% w4 Z) w- S

  41. 1 q8 i3 H9 y7 A% n  ^' ?
  42.            //初始化7 p7 _% E$ Z# s' ]
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
    ) L/ f. v; z) t* r" f
  44.            pilot.reset();
    . p; S  k1 K' v( j  V) G2 B
  45. % [+ K/ }' x2 H; H! y% Y5 C- g
  46.            Delay.msDelay(3000);
    ' ~& A) O9 i/ o3 U1 {

  47. : X7 P0 d0 @, S, G: ^3 o! O1 F
  48.            doublespeed = 10;! ]. N# c: c- b
  49.            doubledistance = 0;0 }. L7 a) }! ?: F+ @

  50. % e  G9 z8 r" I' C
  51.            //起步加速8 i! S7 G. r4 I0 l- _; _% W4 \
  52.            pilot.travel(300,true);2 N/ J' ~& C# T1 Q

  53. ' q* E+ w) Q! _' |* B
  54.            while(distance < 20) {
    ! S7 C( a( Q' l
  55.                    distance= pilot.getMovement().getDistanceTraveled();. h2 a$ D2 G8 \4 @9 L/ ]  q
  56.                    speed= distance * 5 + 10;5 X  F7 b* Q# K4 D2 Z
  57.                    pilot.setRotateSpeed(speed);
    % o( N# J  s: ]$ w7 N" _7 x6 ]
  58.                    Delay.msDelay(100);$ O/ p4 ]7 h3 s/ w+ Q- K2 ~/ y+ O+ P
  59.            }
    4 ^$ O4 D0 E" _
  60.            for(int i = 0; i < 10; i++) {$ V  M# T: O5 K0 J- x, k
  61.                    speed+= 5;
    8 t$ b7 J: F, C" B
  62.                    pilot.setRotateSpeed(speed);
    * Y6 T/ p# p: H1 }2 H
  63.                    Delay.msDelay(200);* V9 ^+ O3 j% J+ U0 P6 a
  64.            }4 A* q+ O: z5 V* u3 u

  65. " D% l; @9 ?4 {! Q& c
  66.            //TODO 减速
    ) y7 {7 i# s2 D! u- p
  67. ; ?  G# C. J0 m# I3 ^8 Y2 W$ `
  68.            //停止机能
    4 v6 q& S: _; n) R* |7 w
  69.            while(pilot.isMoving()) {* j0 y1 }2 A) h! r$ u9 g, N% r
  70.                    if(Button.readButtons() > 0)) E2 Q2 x" F  L5 {
  71.                            pilot.stop();+ a# m" m% C8 ?! y8 W9 G
  72.            }% V' R: K. q3 H8 @* n- c

  73. % i/ w/ ]6 y, p1 H3 S0 n$ V6 F
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    ' Y5 s* P$ x+ ~1 Y
  75.            System.out.println(-Motor.A.getTachoCount());3 E4 L$ W( y& u( f: \
  76.            System.out.println(-Motor.B.getTachoCount());) y( N: `% T( m# }9 @
  77.            Button.waitForAnyPress();( U& v( j7 u( ~2 x8 Y
  78.   }9 @" Z% X+ g, G, l# `% q. c
  79. 9 ?% o1 J! A; Q0 P0 K" c
  80.   publicstatic void main(String[] args) {
    - \( M; p* Y8 S& _% Y! D
  81.            Straighttraveler = new Straight();
    : j+ j$ y1 |* S! t, H; L* |% ~% X

  82. ; u( u  m* |9 M5 R7 U2 u& B) j5 p8 D
  83.            traveler.adjust();
    1 G8 f, |% @6 P$ E3 X+ T
  84.            traveler.go();6 L2 k1 m, n% K! C. H/ k
  85.   }3 v, @# v3 `! _8 i; P$ [
  86. }
复制代码

. O3 s% L3 ^# ^4 H0 n& H
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 编辑 & p$ O4 t& f" L3 p' G

5 G( z& i9 X$ X2 h8 A这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
% t; s; Z) ~6 }. P/ {# o& f这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

) }5 A% v. m& ?9 B5 {& 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-7-9 11:39 , Processed in 0.519846 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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