找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12416|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
/ B0 B# \/ i0 u9 l
* j: C1 T5 g9 z' S8 ?9 n
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

( t; h( u# _# C( z
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
0 E  U3 \8 p( F4 D8 Q
场地
6 j/ c9 S9 E* B& b2 ]1 u4 ~  水平度和光滑度
在家里当然瓷砖的效果是最好的0 P6 t3 l) Y, @; l1 W0 {, k1 h
  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
+ [+ Q$ ^2 }$ p+ _* L5 u0 h& B6 L+ f3 S: Y$ ?
车子结构1 `1 q7 R8 ^) P9 E0 D
  轮子间距4 V6 q' w% ]4 M# ]! G. O
     轮子间距越大越好,稍微想一下便知
2 @) ~4 k4 B) ~+ F8 i% u& Z5 w& h  轮子大小
/ ~, m1 M& q5 s1 l- n, o     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)% q0 U( k! U2 A* h
  随动轮的设计+ j0 B& R) Z% P3 i! y' q
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响" `: A4 v4 s5 p9 y1 K$ e. O
  重心位置
* t0 U; k6 Z  P" r$ p7 K     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小7 U( y) G+ B8 e% \  J. ?; I$ d
  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
2 R! W. Y6 R. _% C% |; m- V  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)1 P/ i5 l9 ~7 B1 N
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动* G% i' p1 e+ |
) l6 B9 o# J; Y. n2 l# D6 `6 H# \
控制程序0 l4 T* ?8 N* o
  运动过程控制) `1 F3 B+ \5 g" t! Z
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
& U3 |" r' v+ j* [; U0 g- C* x
4 x' b4 `' p. F: j% q调试与运行
" K9 S4 W: r( H  H  轮子转速调整(车轮大小的设定)
# o3 f8 p9 Z9 Z$ Z$ K      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
5 \" p2 ~& _/ E/ X+ E  起始位置车子正方向和直线间的夹角
( d& }6 F# D! N6 L' k      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点

/ @% v2 S1 v9 s' T  B% q
( I& ?$ H- U) S
3 _  u5 l& q2 Q" d/ ]
然后上源代码:
  1. 6 G8 K4 Z1 g5 M7 Z' o
  2. importlejos.robotics.navigation.DifferentialPilot;
    " l) O$ T: ]( E5 C
  3. import lejos.util.Delay;
    ( A, u6 r" T4 i8 ^2 Q6 k# D

  4. - o9 ]' Y9 B- U3 u. }4 [" ~
  5. /**
    9 y" z# ?6 D0 _2 }1 h  A
  6. *Robot that stops if the buttons are presses before it completes its travel.
    9 V- E0 {$ A5 V+ l1 f
  7. */
    # ]" F5 P% z# v$ n/ u
  8. 9 U  P) a4 u) t2 Z+ m& M3 t( r7 O

  9. 6 E7 m0 {- E' X8 p1 u5 y
  10. public class Straight {. d5 O/ N+ r1 I2 G1 @/ i+ |
  11.   DifferentialPilotpilot;
    $ H% r8 n) J4 t5 w6 Q0 a
  12.   doubleleftD = 4.3, rightD = 4.3;$ E+ C  k. j; U

  13. / Z7 [: v' c/ P8 j$ X# U( u
  14.   publicvoid adjust() {% M- W- [! K9 {* M6 g1 n. ?( o
  15.            //wait for release6 `  B7 \9 g$ `& O/ n; U. {
  16.            while(Button.readButtons() > 0)
    ) u8 B8 Q& ~: A
  17.                    ;8 |' L+ I! ?8 i$ ]& q
  18.            while(Button.readButtons() == 0) {+ N* _1 p, C) O: p
  19.                    //input size by adjusting the wheels
    4 F0 \0 z1 D5 t* Z* ~  _; h
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    : R  H% g, H& ]( Q
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值5 \% u6 ^; I, ?9 e4 i
  22. " P! O4 [6 i4 c
  23.                    //display the size input
    ! T2 b% r) p  A2 h
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    : Z% R1 u3 M% t0 b; b! B0 j; r! G# r
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    1 O! T2 v2 {# `) y( W) |
  26.                    Delay.msDelay(100);% f8 C, \- ?, P
  27.                    LCD.clear();
    7 r: ?7 {2 r; a( }0 r
  28.            }
    ! y# O6 F1 p. B% J
  29. 9 d; E, P& h3 y/ m" E. N- q
  30.   }
    & t, Z+ r+ {0 `0 }

  31. 1 {2 T$ \) g/ a, l7 h9 I
  32.   publicvoid go() {
    * W) p6 C0 |5 R$ y3 E* @* L
  33.            //准备起步
    7 c" u, @# ?' [4 @; _
  34.            //wait for release
    % @2 L/ u) u6 a3 |1 U
  35.            while(Button.readButtons() > 0)5 i2 C! b# Z$ o
  36.                    ;
    % }& {$ ~) {3 f
  37.            System.out.println("pressto go");7 D1 o! ?) P4 j# \% B& o
  38. % O) \5 p+ X5 c# ]/ y
  39.            Button.waitForAnyPress();2 P! h$ g  z, t( L
  40.            LCD.clear();
    " C, i5 o( u7 v2 r" R8 ^8 ?
  41. , \" s# d# C# `7 L6 Q& B+ T
  42.            //初始化9 O* G! ]: g: j/ C
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
    8 U9 t* P; T& o/ A& ]
  44.            pilot.reset();
    % @+ Q* G# n. W9 M

  45. + P6 q( o- O: _& a$ t2 H: }
  46.            Delay.msDelay(3000);2 i% E* D2 d7 {: _# B
  47. 5 t) }0 e. W* n: L# S. c; G
  48.            doublespeed = 10;( V9 C  x4 {( {' R( Z7 ^
  49.            doubledistance = 0;$ r: U! D3 H1 w1 h

  50. 2 c7 x' ?; G6 U8 S* L
  51.            //起步加速* s- T8 H" c9 C/ o
  52.            pilot.travel(300,true);* t- ?+ U% Y1 p& O
  53. 5 L  C4 C7 k: r6 H
  54.            while(distance < 20) {$ O! w1 e* K& g9 h
  55.                    distance= pilot.getMovement().getDistanceTraveled();% R6 Z8 s6 P  W$ z" A4 o- J
  56.                    speed= distance * 5 + 10;
    6 Q% ~4 d0 D  o' [  [* p
  57.                    pilot.setRotateSpeed(speed);" p( @2 Z6 K1 v) D, R
  58.                    Delay.msDelay(100);+ A: L  I6 \$ k. l. ^( W1 }1 C
  59.            }
    - s1 q* }( q4 x- j
  60.            for(int i = 0; i < 10; i++) {4 V- }4 r" D0 G9 T
  61.                    speed+= 5;2 x. ?" t; Q9 b) }
  62.                    pilot.setRotateSpeed(speed);
    9 H4 C3 B' s! D# p# }2 ?& ?
  63.                    Delay.msDelay(200);' N7 s1 F( N$ Y# d. Y- t6 U
  64.            }2 D+ Z; n! Z' M$ ]7 U. ]+ i
  65. / |% l0 |) H( O$ q- g$ }
  66.            //TODO 减速+ q+ N3 ~5 _9 a7 R0 i) f

  67. / d) a( |7 ?2 I4 B, A5 _5 ~
  68.            //停止机能/ G7 n$ v' L7 A6 g4 ?. K+ j1 X
  69.            while(pilot.isMoving()) {( }$ x& E3 M5 w
  70.                    if(Button.readButtons() > 0): J+ R: w$ b1 ^' R( s! ^
  71.                            pilot.stop();
    $ I/ ^! M+ a  y# Y* x% w" I
  72.            }
    . w  S, k# O, L: `4 l- Q, X2 K

  73. ! M! r: o# o! ^2 m' H
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());' d; y2 w$ E7 R
  75.            System.out.println(-Motor.A.getTachoCount());
    9 v( W" ^4 o& |
  76.            System.out.println(-Motor.B.getTachoCount());
    $ q, Q9 ?) r! u) y: K
  77.            Button.waitForAnyPress();& v* P2 ~7 d' h3 f
  78.   }$ r) t* x, Z4 G1 G8 Q& m+ M

  79. 6 x6 {8 A6 @- o3 j6 E( _
  80.   publicstatic void main(String[] args) {3 W/ f' q: o9 @, w) A5 t
  81.            Straighttraveler = new Straight();
    / ?/ E- }. X* l5 B# Q. T8 V3 I3 ~
  82.   m7 q# q" D3 p, R. _
  83.            traveler.adjust();
    1 M* {! j3 D3 F- S+ j' w
  84.            traveler.go();' d3 }$ b6 X, z5 B" d
  85.   }4 f( K/ V; R+ ^- ?
  86. }
复制代码

: F, C7 U7 M& I0 i
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 编辑 ) w% W4 i6 W  L3 Y# E

7 e$ |* N( s9 w% W5 K这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

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

* R' U( G3 I' x% V, P我用的是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-27 08:43 , Processed in 0.444819 second(s), 20 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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