找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12926|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
) Q5 ?9 u8 o, x& p( X& H9 B1 ]7 h" |9 A8 |4 w% G
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

6 t3 y! T# l# C5 g) l
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
0 N& {3 v4 K0 h) B$ {& @9 Y- }3 a; `
场地5 T1 `# }2 j$ r7 ~0 `
  水平度和光滑度
在家里当然瓷砖的效果是最好的
- e3 h1 ], b! e( k- ^& j( Q, \. o  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直5 X: m4 d4 V) D  t# `1 h

- ~$ T7 q9 [; X车子结构) e3 F! q8 C9 g9 i. b1 @! L
  轮子间距
9 {1 w1 h7 b4 |# I- A     轮子间距越大越好,稍微想一下便知
7 P8 S: r) a9 I0 ?  轮子大小. e0 S/ m) c) U) a, d! J9 N9 U
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)9 E$ P4 B! Q" s4 L
  随动轮的设计
1 A# M5 z9 ~+ Z. U* n& O$ S3 c5 F5 _     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响# V7 G' i0 x8 l( a# n9 W
  重心位置
% h$ _$ ?3 ~: Y     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小. O0 J( Q2 |" |) X$ o; T) Y
  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
, B1 ]/ _0 f/ a) T' O5 z/ q2 C3 i  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
  q5 x, o0 z/ c, ?1 p  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动0 ]. o7 `' [$ y  X# a
. s7 o1 Q  W; _, `# }
控制程序3 _# J/ h# |* I
  运动过程控制
" `& a5 l2 {  d% G3 f$ D     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)2 t! p8 I( J) Q/ m+ i
7 t2 P* }  L  ?/ K
调试与运行' ~' O9 M  D' i2 f2 d
  轮子转速调整(车轮大小的设定)
) a% Y) v( v0 m8 U5 o" b  @      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法1 S. ?8 L6 R) Q- m: _' }
  起始位置车子正方向和直线间的夹角+ N0 Q( U& ^; g/ S+ y
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点

$ W. w) k# H$ d
8 V( L( T- C7 o/ P1 d+ s
2 v# B) [8 ?9 C- C) k5 e, A; D
然后上源代码:
  1. 9 J. W- n3 H; K! T/ j' J4 e
  2. importlejos.robotics.navigation.DifferentialPilot;
    # V+ a, A3 e  [' k% D0 `. h- k5 X4 v, `
  3. import lejos.util.Delay;9 u( L! l% h/ n5 s7 @
  4. - h. W4 T3 {: K1 O( M: x2 n
  5. /**
    + v. r  H+ J+ P4 h
  6. *Robot that stops if the buttons are presses before it completes its travel.% j. h4 q- [9 {2 E* b
  7. */* D0 P+ X9 k+ m2 D' ~' F
  8. + s/ T' E4 b  g8 t" g+ q8 |
  9. 4 G3 |1 a( x  G% |7 Q
  10. public class Straight {
    ( f# e' W9 `2 s) N
  11.   DifferentialPilotpilot;
    2 ^, N' l1 d; @1 ]$ D- l
  12.   doubleleftD = 4.3, rightD = 4.3;
    0 v/ w/ F  N1 g9 c* G

  13. # J. W' X: x  M& y9 P. S& e& i
  14.   publicvoid adjust() {
    : _3 s! |0 K# q2 h. x/ x
  15.            //wait for release& q" w/ b1 y; Y: y+ M6 G5 s( R
  16.            while(Button.readButtons() > 0)
    - x( i3 ?" }6 `2 p1 E
  17.                    ;; ?# D. t9 H# Z/ [" C
  18.            while(Button.readButtons() == 0) {3 ?2 y" E5 Z4 ]! ^+ J1 Z) i! I* L
  19.                    //input size by adjusting the wheels
    6 s' W3 D! [- v3 h5 b* S" {% l
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    / M+ V- Q! j$ F$ i6 w" \
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值5 X9 Z5 f: U' p, S

  22. : h- g- X: ]) z* r# v2 _7 _' d
  23.                    //display the size input
    , h8 v# K# y* e9 W
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    ' W  s! n4 D8 \& W! c! _- y
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);. W6 @5 T! ~) S
  26.                    Delay.msDelay(100);
    4 l1 Q( V- Y; j$ m5 M: @3 R2 J
  27.                    LCD.clear();
    7 f8 s9 u% j4 }, ^  q
  28.            }" E" H1 ]- A6 s# \+ v! f
  29. ! p* z* N+ V- k4 z! t4 m
  30.   }
    9 _5 t6 G6 s0 B: `  m, d0 X" f

  31. + L2 l7 c& `% n' {' F6 P
  32.   publicvoid go() {
    $ n9 O' L3 ^' {, |0 j8 V: S( R# J- ~' \
  33.            //准备起步' ?2 c2 u5 z5 s* `$ a$ ~! g
  34.            //wait for release
    * F) B+ ^2 `- f8 H# P: r$ W
  35.            while(Button.readButtons() > 0)
    3 q0 j7 p5 ^1 e+ e/ p0 o
  36.                    ;
    2 p" u' t3 @8 f2 Q
  37.            System.out.println("pressto go");5 i, _; ?$ A$ {" |0 E3 {2 C( u
  38. 2 ]/ D3 S/ e/ ]( V
  39.            Button.waitForAnyPress();
    0 T, @' {9 T. x
  40.            LCD.clear();
    9 Q5 S7 N  J# u2 R5 B3 W* Z/ g% Y  {

  41. 4 K6 q" K% H( J6 l0 t% [+ j9 \
  42.            //初始化
    2 L- [% U. |7 V# O
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);9 k( m2 \' J# S9 L
  44.            pilot.reset();
    ; S$ [3 D7 B1 m! [
  45. $ }5 d. s8 X) L
  46.            Delay.msDelay(3000);# h4 I2 C$ y3 @! I% w
  47. 7 i% q# U$ r# c, b' }# u8 |
  48.            doublespeed = 10;
    * n) h  X- S% T1 r& m  F
  49.            doubledistance = 0;
    1 d1 ^7 m1 T' }- u, B* z$ G7 T
  50. 5 v2 q) D9 T0 ~# t
  51.            //起步加速$ K" H) n( D7 x) C7 V7 |/ O3 f- [* L
  52.            pilot.travel(300,true);" ~9 M; S2 |  X: g2 C3 J& _4 Y. a
  53. 3 x) P2 J6 x1 ^4 m
  54.            while(distance < 20) {
    1 A) y( [( W! b3 j9 l. V, I
  55.                    distance= pilot.getMovement().getDistanceTraveled();' y' m  ?4 G  t: P/ j6 b' a
  56.                    speed= distance * 5 + 10;
    9 L% `) d' V- g, t
  57.                    pilot.setRotateSpeed(speed);3 g/ A8 p4 ]1 w
  58.                    Delay.msDelay(100);
    + D" `; {9 T3 {4 ^2 R+ i% L0 K# A( t
  59.            }$ |  h9 r  I  f' w5 Q# |( @
  60.            for(int i = 0; i < 10; i++) {
    0 E: c2 t. k8 M3 A9 e1 N
  61.                    speed+= 5;
    9 _( z( j% Q) c" ~
  62.                    pilot.setRotateSpeed(speed);
      a- @$ c2 M+ ~# {' t
  63.                    Delay.msDelay(200);
    2 l3 v9 J0 _' z7 e* H6 u# z9 M! Y
  64.            }8 t- D" d* c- T

  65.   {, o% ]4 T4 s
  66.            //TODO 减速
    5 t8 ~0 Z4 E1 L: @* a2 K4 x

  67.   \. a2 h9 S+ @& a2 x) C% Q
  68.            //停止机能! q, r2 ~% ~, C5 t" U, k
  69.            while(pilot.isMoving()) {
    % r: H! W! y% u: v3 |
  70.                    if(Button.readButtons() > 0)
    2 v" j$ F2 h$ Z% T
  71.                            pilot.stop();
    : H# q" _$ [% t+ p9 u, D
  72.            }5 @# T. F! P" {# n3 [5 T

  73. + S7 o& P7 P- K) A
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());* A8 [$ G) m$ I# f9 }' U
  75.            System.out.println(-Motor.A.getTachoCount());
    # }. [  G& H$ Y4 n# V! y5 n/ W  G; P
  76.            System.out.println(-Motor.B.getTachoCount());7 D) B- k& C4 T- \3 t
  77.            Button.waitForAnyPress();
    2 l, \- h' d/ ]8 e
  78.   }
    % C6 J7 g2 N$ t4 ~4 l* g  @

  79. " W9 i4 S& n! s/ V% w0 R% _
  80.   publicstatic void main(String[] args) {
    ! l( G( W/ h/ H8 T% g3 q1 F
  81.            Straighttraveler = new Straight();: D0 F7 L: |3 y5 a: `* }: V! X( v; f$ Y1 n

  82. " Q0 E' w5 n) b1 o2 `- n/ m
  83.            traveler.adjust();) ^) [' d" y/ Q4 ]0 v# E5 M! d
  84.            traveler.go();
    : T! Q) Q1 j3 w* m
  85.   }
    ) |, n! m% A& _2 V5 @+ O+ s" I/ r
  86. }
复制代码
& N4 z9 q% T1 t, B
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 编辑
# m. R* t9 P+ L0 q- {; \: k( J: A, f$ H. |3 b, t
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
: R7 K# d5 ~% y4 y( {: S这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

7 v  P: E# {8 j) M我用的是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-30 03:20 , Processed in 0.395435 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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