找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 13144|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑 # U9 _: X5 M/ d' Z# z3 `
$ ^  i; T$ b0 q
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
4 q/ r1 y. r' x" |. J9 l
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

: c6 _& H1 }  g- J/ t) j
场地3 J; L( p- B- V1 @! L0 v* _, R
  水平度和光滑度
在家里当然瓷砖的效果是最好的
( @( @  @. B3 W' \& c+ W4 H( L) F  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直! Y; |' g  y" y# ?. l

$ v: f: c+ N4 U. a: d8 I' v车子结构
* r& l8 X6 C5 @4 ]  轮子间距& ]7 z8 s( M: a4 w/ X3 E
     轮子间距越大越好,稍微想一下便知
/ Z8 x, _' Z- A$ h: b# f: q  轮子大小
! H0 w0 F  r, I4 n( l     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
3 U0 k+ ~- D& W4 ^0 ~8 X+ a  随动轮的设计  B# H4 ~" Y- \2 p& W
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响$ z" H/ J) R- U0 ?  k
  重心位置
* U' W1 X9 f/ R- f6 y! g2 {     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
, O- d) X* u/ `& l; a+ g, X, h  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
' G6 T- L% i2 l" |% {7 I7 w) S  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
! _/ v; s$ c$ O% ^  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
& z* }9 m( p% ~  m$ W, G. i) v) V
5 p" o5 O# `! W; p  J控制程序* g( c  p* r/ Q, L9 g
  运动过程控制
4 i3 {. D2 ]3 ^! v     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
( W$ h' G! N! e  W
6 w7 }" D7 J" n) A调试与运行
7 J$ E* w# |: _, Y1 [  轮子转速调整(车轮大小的设定)7 O! D/ u2 N5 j. H4 K- ?4 W, G
      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法1 m9 I$ }8 `4 {& k% n
  起始位置车子正方向和直线间的夹角
0 Y$ E: u* ], {$ H      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点

/ w8 Y3 K: Z. U6 F& x
5 Z. l) E3 [( Y" F6 `2 D3 I
. W* v/ ^' k3 y
然后上源代码:
  1. + p) q; @7 y0 Q6 o
  2. importlejos.robotics.navigation.DifferentialPilot;
    0 o, D/ J+ {, _
  3. import lejos.util.Delay;
    3 f! B4 {/ d) u3 Z7 b/ }
  4. 8 p+ J( D3 j5 ^# q4 G7 ~
  5. /**
    6 Y  e: i* r; `- u( r
  6. *Robot that stops if the buttons are presses before it completes its travel.5 m. _; o+ Y; K/ {% ]
  7. */
    . T" \7 \+ D7 S$ i/ S/ G- w

  8. 3 g) B$ J1 n& K" ]8 v

  9. 2 u8 V6 ]% V/ P/ \5 o) _" q( L3 m
  10. public class Straight {
    ( q/ E) K4 T1 h
  11.   DifferentialPilotpilot;
    ) D1 {2 M2 w# ?* I: ?2 A8 }& l
  12.   doubleleftD = 4.3, rightD = 4.3;3 `8 ?3 D) m& L9 G) P, J

  13. ! d0 Z; S2 `/ `$ ]3 n
  14.   publicvoid adjust() {" e8 W% u3 K+ k
  15.            //wait for release
    2 f1 L" M0 x4 {) a& V
  16.            while(Button.readButtons() > 0); |  h0 c! v- A& [" F/ w
  17.                    ;8 c: s/ p5 A. x# N* ~3 |
  18.            while(Button.readButtons() == 0) {
      ]1 W0 l1 Q1 v' H8 w: f& f* y  p
  19.                    //input size by adjusting the wheels
    1 b6 |# |# p3 O/ P4 W# B7 T
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    / J. p9 T( R. C& S7 C% X" \
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值
    ; [# N6 G9 E6 p' G

  22. + X5 E$ E* _* z
  23.                    //display the size input) I! K2 o0 |  M$ Q) h& M8 Z$ h
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);5 _6 v2 |" _; `
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    : Z1 p. ~  H( |2 E3 ]' y
  26.                    Delay.msDelay(100);: Y7 |; b: g+ _
  27.                    LCD.clear();4 e9 @" }" _1 [5 j
  28.            }3 s- F9 }- p) \- N
  29.   j( W; a( y5 `# ^! g4 S* S
  30.   }
    4 Q4 z/ o1 ]8 W  z% G& c. J# A

  31. ( X- U7 E) D9 R5 n6 Z
  32.   publicvoid go() {
    . c. U( ]5 _' p# n9 ?0 `& n
  33.            //准备起步& J, G* L+ a& Y" U
  34.            //wait for release
    $ _8 S5 G8 |7 v. |" s7 N: m
  35.            while(Button.readButtons() > 0); I; w9 {. d% v5 A# g8 w
  36.                    ;* E  b9 U& f8 x$ Q6 @: f( s
  37.            System.out.println("pressto go");! Z: D: S  O% h
  38. ; l2 p; l+ d! D" `
  39.            Button.waitForAnyPress();
    6 k, F1 Y0 N+ h' I( U
  40.            LCD.clear();' u' P5 ~1 @' X' q) b) j

  41.   e7 T/ @3 d/ e
  42.            //初始化
    $ Y" v+ r' H! L+ X
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);' _2 M1 m' @/ I# U" i4 v
  44.            pilot.reset();% [( R9 T" G% W9 S

  45. # i" r" L' W6 l
  46.            Delay.msDelay(3000);
    ) a" x- A& m9 u

  47. 8 S+ T6 |# A$ b! x% {; `: A; D
  48.            doublespeed = 10;' H0 l5 B  P# a" B
  49.            doubledistance = 0;2 G4 X4 f7 Q  l0 Q' |" }

  50. : }$ q  J* x' s8 o
  51.            //起步加速& {* M' r: x( Z7 F) r
  52.            pilot.travel(300,true);
    6 M1 O. H4 {% u  p
  53. 8 d2 ?% u( d1 U; G, T! a' }  X
  54.            while(distance < 20) {) ?8 b) V6 [0 P+ N7 R" a2 M3 J
  55.                    distance= pilot.getMovement().getDistanceTraveled();
    + @& s3 r$ Q+ N
  56.                    speed= distance * 5 + 10;
    # h1 {& D7 W$ O2 R; C
  57.                    pilot.setRotateSpeed(speed);
    + ?* k! B5 u# p
  58.                    Delay.msDelay(100);4 u3 w0 T; r( n5 x( M
  59.            }( Y% Y  _1 E# x2 z
  60.            for(int i = 0; i < 10; i++) {
    . ~: ^  E8 q2 `9 }: c' E: Y- _
  61.                    speed+= 5;
    * N  P9 ^0 r1 z% u7 t- H
  62.                    pilot.setRotateSpeed(speed);5 [9 p; h- s/ M7 D) P
  63.                    Delay.msDelay(200);
    3 `3 W( R" j  t/ t; u, x
  64.            }, W9 w1 u5 s9 U% c9 R" T
  65. 9 m, m) J3 M( \1 B& V0 U) G$ g; }
  66.            //TODO 减速, ^5 z3 _! a# D

  67. 0 x( J6 d1 y. p+ ~8 G: u
  68.            //停止机能5 Q) _. O" N$ t" H
  69.            while(pilot.isMoving()) {7 Z  w& \; H" Q: O% H
  70.                    if(Button.readButtons() > 0)
    + F2 S$ k) N8 ]6 `  Z
  71.                            pilot.stop();) g( m* y2 X. N/ L
  72.            }
    ! L: q. y+ q% T) h

  73. ) P0 X( W& d8 a1 r
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    9 \# n2 }, d+ m% P1 K
  75.            System.out.println(-Motor.A.getTachoCount());& H7 C" |+ o! O3 G* _% t
  76.            System.out.println(-Motor.B.getTachoCount());
    $ S" H0 x! L; j0 U* f
  77.            Button.waitForAnyPress();& ~% }2 j( A3 D, B
  78.   }$ N" Y- G. B! @- C: n9 G9 S+ I
  79. 2 l  `7 m1 x! v% o1 z1 U2 C
  80.   publicstatic void main(String[] args) {; o, N: W1 h( M) D  f. w
  81.            Straighttraveler = new Straight();3 X+ _# T) N; v) Y
  82. 5 ~: b8 C( _- A
  83.            traveler.adjust();
    9 e3 i! l0 Z' B- ~# x1 S
  84.            traveler.go();  k3 g' g9 O& M: {; K0 s
  85.   }
    + ~- T1 x0 y6 E
  86. }
复制代码
9 @+ A* J( ~7 K5 U9 o
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 编辑
1 c( V* A% j  J* O5 F; J5 w* n! s; z4 o# p: ?6 Q: M6 y* S8 k
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复 赞 踩

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
0 j) G) H' u( {9 o5 Y4 w+ R这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...
+ c* i, h( a: x7 [$ h
我用的是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-9-26 14:43 , Processed in 0.417210 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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