找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12477|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑 ) o9 v# @7 j' M# N% K" \6 l

. p; c8 A( w5 G, s8 y5 ~
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

+ X& G: t* Q; H: W4 R8 U$ y% o
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

0 `( r5 z  m: H  s4 F* s% Y- K0 M( o
场地( x* v) g* K1 _
  水平度和光滑度
在家里当然瓷砖的效果是最好的* h+ H( S# y% _9 @9 b* h% j
  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
4 s& n# o" W. l+ o- v* _2 z4 ^# M5 D- q
车子结构
5 {# b7 P, s; G8 x+ C4 s0 S  轮子间距0 n8 t& x& D7 Y$ M; ^, ]( W
     轮子间距越大越好,稍微想一下便知" v0 N" V8 @, C  B3 n) \
  轮子大小
* d* T: ~7 m; R( O7 d1 t% o3 ^, ]     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
! T1 v, [1 j8 l7 }3 L+ t  随动轮的设计$ \/ l8 L7 N7 `" D. v) I8 E7 q
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
3 w7 [6 C' s3 Y  重心位置
! A+ O# T1 A3 U, B6 {' C3 ]     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
0 M; Z" Y6 @  Z  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大$ _* R. b7 E& {" s! }& Y2 I; N
  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)8 A0 E1 U+ _3 U  |* {
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
$ ?) H; J9 P3 N0 G
4 m' J( O6 P- w! [& m$ ~控制程序
" B3 B6 h* M: k5 F# Z4 \# E3 [  运动过程控制( f  _' K; v5 o7 ^( a7 o6 B5 F
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
; z  {1 p& \( e/ t& Z8 y# C, P6 e7 D3 u' s- ~$ _  }
调试与运行' y: C. j6 [/ S, [1 X. F) u8 i& I
  轮子转速调整(车轮大小的设定)
! K1 h+ s, w8 l+ z; [3 D6 F      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法$ i" a( T. G4 I+ ?! P
  起始位置车子正方向和直线间的夹角3 E1 f+ @. I* X" |4 a
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
' _4 ?; `$ R, n' S4 d

, q7 J+ z0 Z. u
4 V9 t( ]' P/ h9 E- N+ L
然后上源代码:
  1. / Q+ j6 N; H; F% _) y, F0 {( R
  2. importlejos.robotics.navigation.DifferentialPilot;
    0 j: c9 n- y$ m, z4 {
  3. import lejos.util.Delay;
      o% ]1 q: |, Y# Y( d
  4. ! @9 v% \8 Z8 \
  5. /**6 l# v3 V0 v" f3 p* w
  6. *Robot that stops if the buttons are presses before it completes its travel.
    ! V$ s! t1 L% G/ s3 f9 \& |
  7. */. ^8 \$ h9 s3 T2 `# S

  8. / f6 s$ p; V- M8 H: b
  9. 5 l2 L/ x' F! ~/ [) D
  10. public class Straight {7 \; L5 C& q# _
  11.   DifferentialPilotpilot;
    ' k# T% s) w1 X- T7 W* V( g; Q
  12.   doubleleftD = 4.3, rightD = 4.3;% `& c7 P2 {# o7 }1 T4 `' u2 j$ g
  13. 9 Y" b" w! |- s) P9 m, A/ H
  14.   publicvoid adjust() {! p3 |$ V. b2 Y5 S/ _% |; y
  15.            //wait for release, Q+ |6 y5 c' N& Z
  16.            while(Button.readButtons() > 0)
    % F. W9 v( k% R* d0 K8 z  y& M1 I
  17.                    ;
    ) ?! j9 j6 G# N' h) E) M+ P
  18.            while(Button.readButtons() == 0) {) m# m" h1 E$ s3 j0 E7 k
  19.                    //input size by adjusting the wheels4 B$ A5 M) h+ P3 p. {; U6 q' u
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    ; ~: O% K; W8 }0 T  ]+ T6 S7 n
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值. h9 g  x  Z: E0 ]7 p2 @( Q2 @

  22. % [2 R# l6 m' w6 f7 S
  23.                    //display the size input
    " `* Y, R; l. g5 G* w% c# G: f( J( x
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);3 e1 m: y! k* J. D' k2 r$ ~/ G$ V
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    0 J# t3 e, ^$ A; P0 W/ j, ?
  26.                    Delay.msDelay(100);
    $ o8 y# h. x) i& O
  27.                    LCD.clear();; e6 ]3 R' E  T- {
  28.            }- z, o/ Z$ ?" |0 l7 o" {6 d0 H9 N

  29. 7 N$ q$ n9 V% A2 e5 v* t5 }6 F/ T1 q
  30.   }/ G$ o4 C- g+ p5 p: E& k) u% R, i5 b

  31. & ^3 a# @: l+ Y' L
  32.   publicvoid go() {" O# L( H/ D5 v. ?$ v; U) i
  33.            //准备起步
    ) v0 |5 h' r0 p
  34.            //wait for release
    ; `/ [+ {$ u6 {1 Z( R& w
  35.            while(Button.readButtons() > 0)
    % ?4 u; A. W: w/ `. V3 k" K
  36.                    ;
    6 ]1 {! ]% ~1 R. l( @
  37.            System.out.println("pressto go");
    % n/ x2 W+ U# X

  38. 8 V. n- j. |; \/ n
  39.            Button.waitForAnyPress();8 j$ Y. \7 u' a2 N# \. k: u3 T
  40.            LCD.clear();+ G$ i6 s& q4 W/ [" k  P

  41. " Q/ g' S/ m: i" w/ K( Q6 v1 I1 }
  42.            //初始化5 p1 g2 g& K2 Q! T8 l7 W
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);& q; [# X  |1 S- j( Y# W
  44.            pilot.reset();2 O( f0 H" S+ i

  45. " o! J  b  \5 d& F! [0 A- O
  46.            Delay.msDelay(3000);  v) L' V* t$ _( X1 C  C

  47. " H& ~% ]9 O8 Y  e( t; x
  48.            doublespeed = 10;
    ; t0 z* h/ I; Z3 ?! B
  49.            doubledistance = 0;
    , b. Q% m; _/ a: [( R' n4 L. {) |
  50. 9 V) h/ \+ L- g3 l- d7 U
  51.            //起步加速! H/ L. L) w8 b2 w% y) z
  52.            pilot.travel(300,true);
    1 i% Z6 r- T# b/ `& a( p' U

  53. " I5 c/ s4 `& _
  54.            while(distance < 20) {
    , `9 k# i% I8 a% P% J* Z7 c2 U
  55.                    distance= pilot.getMovement().getDistanceTraveled();' X2 L2 B! M2 o3 {0 K7 _
  56.                    speed= distance * 5 + 10;; S6 r; d! ^4 I, ~+ ]
  57.                    pilot.setRotateSpeed(speed);
    ; u) e! u; `+ p1 Z1 `
  58.                    Delay.msDelay(100);
      P5 H5 P- q$ v
  59.            }. U5 e! Q+ p5 Q" `  i9 @+ V# L' P. G
  60.            for(int i = 0; i < 10; i++) {
    ( }% M9 `, m3 d/ }1 h
  61.                    speed+= 5;
    / Y# R& {7 H( j# z, ^! |/ E
  62.                    pilot.setRotateSpeed(speed);/ J; O3 _3 Y6 J  S9 c3 e! k8 c. R
  63.                    Delay.msDelay(200);& ?$ `4 u1 l0 `5 m! E& P( X
  64.            }
    & z: R* `( f  b" U, d1 s3 k7 Z

  65. : J4 \& g- C+ B$ ]# Q. B0 T
  66.            //TODO 减速! Q, j* w" W* c& @

  67. - E. j' r( X9 ]" V# L! `$ \
  68.            //停止机能$ k' O0 \, ?0 k( u* a0 h
  69.            while(pilot.isMoving()) {
    * b0 }* v1 H- ^- M' W' @3 o0 N! P
  70.                    if(Button.readButtons() > 0)# ]6 W% h$ H! P0 _
  71.                            pilot.stop();4 o9 j4 M8 }/ [- G0 N) ^; y. j
  72.            }
    8 E3 ~2 n/ G: R0 r0 Y

  73. : n3 S5 ]0 m, `7 Y3 ]
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    8 D1 i/ u% a  I
  75.            System.out.println(-Motor.A.getTachoCount());% c- f1 q) K- p  i
  76.            System.out.println(-Motor.B.getTachoCount());
    - e. ]# \# [; N0 d
  77.            Button.waitForAnyPress();
    0 q- [6 \( q1 u! [) Y& u7 \
  78.   }# ]2 h; z, ^' }
  79. * a6 I9 I1 n0 V$ T5 Z. ^$ @
  80.   publicstatic void main(String[] args) {! b) r7 H, i! }4 R
  81.            Straighttraveler = new Straight();
    : y0 I- o' I: T

  82. 8 O  K# o) E0 p4 S
  83.            traveler.adjust();0 y4 M! l, i8 c/ b7 w7 E- a
  84.            traveler.go();
    2 k5 A# D2 V; a" n4 q  Y
  85.   }& _2 G* y3 p7 K" X- U
  86. }
复制代码

$ L7 m1 }  S' q0 r
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 编辑
5 L4 S8 b- B4 W4 S) \2 F8 a) i/ ]; h. S! S0 C( w' ]: r
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
/ o4 v2 E9 E, n+ o这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

9 Y, D1 L. h, Y+ R% d我用的是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-4 12:22 , Processed in 0.497063 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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