找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 10873|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
3 _/ \5 D0 u+ P/ H1 P( Q2 {6 c1 O; }
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
  \4 W. Y' g2 S
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
+ o, H  ]6 s3 O+ U# j
场地
. _/ H# C8 g" {( a% J  水平度和光滑度
在家里当然瓷砖的效果是最好的
5 w, R! s- w+ h' t% W% J  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
& ^7 G( p2 r8 Z) M/ C- x( @3 O0 }( F
车子结构
0 u. D) h0 L; O) n  轮子间距/ T5 g: C# d3 l2 ?7 {4 O7 C
     轮子间距越大越好,稍微想一下便知
4 ^1 W  h  ^; H' Y  轮子大小/ H* H9 U: k& M8 H7 j5 u. T
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)' `9 a/ M/ m* S: d) I3 F! v/ F
  随动轮的设计. \, _+ C* R4 q  R1 A' o3 Z
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响; u% i/ m5 r. a/ \' [1 O$ p; t* i. b
  重心位置
% W( t5 o9 c& [8 O4 u3 I     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
' Y8 j" S$ S" Q# f3 W$ C0 k  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大$ o7 X( u: W6 x. F
  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)0 }1 x: p# U4 Q: l( B
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动0 y8 k" Y9 ~( k% W
: c2 H. @# K! J
控制程序+ U  J6 a. {6 L; t0 V/ m
  运动过程控制0 J8 M$ U$ x& O2 E4 O6 ^$ s
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
. C/ s6 M% e" a2 F  S) Z, V) G
" v0 a- H7 Q" c" X调试与运行
" C" U5 S3 ?& ]3 h  ]( b  轮子转速调整(车轮大小的设定)
& `% W' F8 Y: B( [' }      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法8 j' z, I# v% Q
  起始位置车子正方向和直线间的夹角
. r3 f" O0 w7 n+ A+ M8 f% C      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
; v- b8 v9 Z2 E/ U
4 K9 m) _: d1 {* R
0 i# D- o. k1 t7 x8 ~, l  k
然后上源代码:
  1. 8 L" Y  O- y4 j* @* S
  2. importlejos.robotics.navigation.DifferentialPilot;" t6 Z. @- x  E0 `& d
  3. import lejos.util.Delay;
    9 K( G& ]2 N- i; J

  4. 1 _9 ?5 b0 d. U% I* @) v
  5. /**
    1 G3 U) v5 p. H
  6. *Robot that stops if the buttons are presses before it completes its travel.
    " j: W  G; R+ e7 _: n
  7. */
    # D; z/ W, v* o$ g5 ]
  8. % U8 r# N2 O, }6 j1 t1 X

  9. + M2 ^' B- E; m6 o8 m
  10. public class Straight {: i6 p! Y# @. |- a1 M
  11.   DifferentialPilotpilot;
    " I, v+ d# n# b! _" u8 M* I3 u
  12.   doubleleftD = 4.3, rightD = 4.3;
    4 s, L$ x. s7 e; ~: W( [8 _
  13. , M  B# K2 @  {  f  g4 D
  14.   publicvoid adjust() {
    1 J; ]# L: S/ Q$ ]2 v& \8 `4 B
  15.            //wait for release
    % O5 u( k& D8 n4 h2 x
  16.            while(Button.readButtons() > 0)  z, O. E8 g& C# [* [! q
  17.                    ;2 ^1 }: ^1 [& O/ h4 Y, r% n
  18.            while(Button.readButtons() == 0) {7 u# m2 W+ I0 V' g, F; D4 }
  19.                    //input size by adjusting the wheels6 p' i3 I1 z( t+ a! ]/ m+ _2 H
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    : D* p( j* ~3 o2 K; A
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值) G% _( Z) c& y! O, k- K
  22. % V$ c6 _3 o. G/ k* e& I& Q
  23.                    //display the size input/ p- O' r/ I7 {/ j  p
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
      Y% Q9 t& f0 O$ ?- K% \8 Z( E+ o% [
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    ' ^1 n. @: {2 @$ f5 ]) u
  26.                    Delay.msDelay(100);' _" f4 G, z! }2 Z* t5 h
  27.                    LCD.clear();
    - @9 ^+ L) q; X
  28.            }+ q4 U. T" x; m- g7 O; t6 E

  29. . t6 }- Q$ V& ]5 E: A% ?6 @/ ~- @
  30.   }; f0 H! ?: m# _# y  M( D
  31. 8 e" y+ j2 T+ N8 h- |: d3 W: r
  32.   publicvoid go() {
    6 E/ Z, \$ Z' B$ Y
  33.            //准备起步! |$ R' T! U# h- ^
  34.            //wait for release
    / v! n5 [& v' b6 D  S- ]: V
  35.            while(Button.readButtons() > 0)
    , T( N, |! P6 X7 Z; {# \
  36.                    ;/ ?/ {6 H9 T2 F8 U
  37.            System.out.println("pressto go");
    4 m3 C% ]) T- |  ^( F8 [  S. ~) M/ {

  38. $ ~8 c. b1 F2 t# u  ^9 r+ N
  39.            Button.waitForAnyPress();
    ' z. {' a; X# i* w/ U
  40.            LCD.clear();
    ( Q' ?1 _% Q4 h
  41. 4 s$ k7 Z, R5 l
  42.            //初始化
    ) j# O5 J6 w# |  t7 L& s
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);1 _+ X( ~* e8 s) g/ F, {9 ~# e
  44.            pilot.reset();
    + B5 D$ s0 `/ y# E, k( u0 Q+ V7 f0 g# V

  45. - \( c) P! o9 R" Y, y
  46.            Delay.msDelay(3000);
    , W7 Q! @$ A0 o! R% k' B
  47. + l% Q4 ~: V- Z
  48.            doublespeed = 10;4 r: t% f1 }% {
  49.            doubledistance = 0;
    4 O3 m/ D! V* E9 E; H
  50. $ X* ]" y6 c  m
  51.            //起步加速
    ) _( c; e. w8 |3 Z; |) h7 \+ L
  52.            pilot.travel(300,true);  q& J9 _. q. M9 R! C

  53. 3 L; T( j/ y( S2 U  [/ B2 I
  54.            while(distance < 20) {& x& s) K8 j  [
  55.                    distance= pilot.getMovement().getDistanceTraveled();9 H7 F7 \9 j7 Q
  56.                    speed= distance * 5 + 10;- p: H* u  ~5 H
  57.                    pilot.setRotateSpeed(speed);
    2 }8 s. s; k) c( c% q# J
  58.                    Delay.msDelay(100);/ `, J3 K$ K9 m8 O# W5 ^
  59.            }
    + u. n( l8 q3 g. L( _& R& q
  60.            for(int i = 0; i < 10; i++) {
    8 {; I7 X/ T3 T% [4 C
  61.                    speed+= 5;! F' V% `9 \9 a1 C% o6 U
  62.                    pilot.setRotateSpeed(speed);
    7 \3 ^" Z8 K0 Z) Y9 C, I
  63.                    Delay.msDelay(200);& ]% o7 F' s+ h0 {" }, b
  64.            }# V/ \- [" m; H$ S+ |* E, l; C

  65. " ]3 s- @" T  |- k# Y: s5 }
  66.            //TODO 减速; p/ o6 n# O" K+ d: P" X/ U

  67. + L( ~$ `3 n! D0 D& V) w- m
  68.            //停止机能' v1 K4 G: O% k1 O
  69.            while(pilot.isMoving()) {' P( c0 f. B# ^; D
  70.                    if(Button.readButtons() > 0)
    8 y) E8 Z$ Y7 l! N$ S
  71.                            pilot.stop();
    , G" U+ g+ c9 E' v, o
  72.            }" t- w3 W+ {2 S8 D
  73. 1 ~. G; \5 @: `7 [7 w. {# k- t) F8 F+ |
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    - U7 u# X4 D4 I/ X( G
  75.            System.out.println(-Motor.A.getTachoCount());
    / o4 d, }0 B3 y, n* w4 a( H
  76.            System.out.println(-Motor.B.getTachoCount());) X' w3 L8 T$ ~
  77.            Button.waitForAnyPress();6 ]/ V5 @# X1 V/ p! ]
  78.   }' R* p* c  y0 S: U. F9 `) p$ ?; i
  79. , F: }5 Z# Q4 \8 f$ |
  80.   publicstatic void main(String[] args) {
    $ d( k6 k5 \" H, h
  81.            Straighttraveler = new Straight();
    . Q- U1 ^2 i7 z1 w1 m' I$ H) a* z
  82. ; o7 k% a0 Y2 s( \& |+ J
  83.            traveler.adjust();
    % b( g9 K0 m6 r$ L
  84.            traveler.go();$ ~4 {7 P* l2 a  e6 Y) u% V
  85.   }9 f* A" ?% w# d- s( j
  86. }
复制代码
- Z. t" B+ g5 _
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 编辑
( L8 {+ e; j$ |) ?$ x" |6 N7 X: {  K1 ?
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
* K4 ~3 i; [: K) U" A. x这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...
, G) l1 _0 T; w, ?4 m8 G. \
我用的是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, 2025-8-16 19:12 , Processed in 0.894028 second(s), 20 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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