找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 11520|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑 " q" w/ _* |% P# L
0 i/ L6 ~' [/ F7 C! @7 e, R1 E
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

! N; C. t9 S+ Y4 E2 \6 L5 p- d
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

2 q: S/ x8 a7 W/ Y
场地
% h; F, }) i- |0 n7 B+ r  水平度和光滑度
在家里当然瓷砖的效果是最好的
2 h2 A* f" B: p+ l  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直, N! k+ v4 o/ _  k: N
' O8 N+ h/ c3 G. G, n. E; M( i
车子结构
3 K' s) t, U5 w, M8 C6 x  轮子间距
- K: Z* t' }1 t3 r1 n0 ]     轮子间距越大越好,稍微想一下便知5 a8 B# e$ N5 J$ n6 r7 |
  轮子大小
2 ~4 S. U" A, u* c2 n- f     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
7 D, R  l, S1 B4 a  N/ ?2 L  随动轮的设计
- _8 H- g7 i% S2 W( e/ F     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
0 `& Y' I9 }5 x" a9 k) ~% j( t  重心位置
, n% h4 a4 ?( }8 x$ p# I+ Q) P     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
. ?# W8 Z/ E% ^" f0 j' e: l& p  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
+ N" g! F& j# S. Q+ ?$ }* Z  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
0 o* }. B) z/ d7 ]0 ?  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动: k: Z" B# W  c& Q$ X
% H& I/ w8 R: b! K* @& N
控制程序
: q) s5 U0 g' ]5 ?/ Y( @+ P# B  运动过程控制4 {8 a8 R& o4 i3 G3 ~
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)" C% l# W2 [8 ^

/ v7 W3 w% O' N' K. b1 @调试与运行
" R% J: c- l& j$ f  轮子转速调整(车轮大小的设定)
1 ?! [% b) L' v2 j& S# g      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法3 ?+ k6 \; O% q
  起始位置车子正方向和直线间的夹角
7 W1 H# f; }1 D! q+ z9 e      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
! D3 {; I$ Y: k. h/ T6 }
9 j! A$ B1 g! }. g
8 b8 u4 T5 G  x1 d+ g, E: `
然后上源代码:
  1. ' W# _. p7 q1 ?
  2. importlejos.robotics.navigation.DifferentialPilot;6 W' C+ J5 \0 ]) G5 _* B- ]
  3. import lejos.util.Delay;
    ! Z4 E' H4 g( R4 b& a* g
  4. 6 B8 N3 k0 y+ `/ F- w2 B  g
  5. /**; Z6 {7 X/ y* k/ \5 H7 x4 G
  6. *Robot that stops if the buttons are presses before it completes its travel.- z, [6 T& G, y6 ~$ g
  7. */' P: `1 n4 m1 T' k0 b
  8. ( c) V: _. a! k3 W
  9. 6 {( Y. a+ C( U# r$ p, {& b6 I( v
  10. public class Straight {
    : @1 r+ i" S: X. u
  11.   DifferentialPilotpilot;
      H+ P- \) Q2 w
  12.   doubleleftD = 4.3, rightD = 4.3;
    5 ~2 d6 r: f, T* n9 v

  13. : n6 C+ G9 n0 j) `7 A0 p2 F* p
  14.   publicvoid adjust() {/ J0 E8 i: }% r: m
  15.            //wait for release
    - t# f* N& D( j: P7 q
  16.            while(Button.readButtons() > 0)
    ; b' J( v7 l: i' e' s
  17.                    ;
    2 K0 }5 p9 x* j
  18.            while(Button.readButtons() == 0) {  z$ u2 w3 x3 s% y& d
  19.                    //input size by adjusting the wheels
    / ^: L9 ~9 B" x" w7 x
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;* ^. {2 b- {4 \$ g1 q  G
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值! `: z, m; n( N3 z+ m

  22. : m$ o9 ~4 G% @0 [) ^6 ?
  23.                    //display the size input' A" J6 b- h* n* g' c  V
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);, w+ r! |' A8 c) l' R0 i
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    ! i8 F* {  C) q) V4 a: x
  26.                    Delay.msDelay(100);
    / Y+ y! y0 y1 h$ W7 c; k; I0 q
  27.                    LCD.clear();
    4 V$ ]% h; P- T* v( q( K! X6 z
  28.            }8 P  K% O9 O9 ]% y

  29. % i" B3 k7 ~6 ?$ s
  30.   }2 ]2 g4 i; v2 Z8 g0 q$ y- x; U
  31. - U6 ~$ f0 G2 E* w" o! E
  32.   publicvoid go() {5 y- E" A9 ~3 `$ N# n- R4 j- I
  33.            //准备起步" }8 h# a, V* u* C
  34.            //wait for release
    6 z" E7 X* k2 E# |( z
  35.            while(Button.readButtons() > 0)* t4 k  f* T' c0 c5 X# T+ W" l8 D# A% p
  36.                    ;
    & S) ?% V' w. Y- ?9 ?% p- J9 J) P4 v
  37.            System.out.println("pressto go");
    ) p) e% X; s! p9 B% R
  38. 3 c+ t! T, m& j# X
  39.            Button.waitForAnyPress();. k; N' F' Z8 g1 H2 W& o0 h
  40.            LCD.clear();" j6 t( P, C, ?/ |* }7 C4 W; y) u
  41. / d3 p9 O8 f  }5 W* H/ h" y+ ^
  42.            //初始化
    7 h2 z4 {4 N# D$ P  o& s( k. g- c, x
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);, g8 ]- A7 w1 d  N* V
  44.            pilot.reset();
    2 A5 a4 o. C6 R( _. O' d: L" L
  45. # I" d9 _3 E) ?1 C" h3 g* S
  46.            Delay.msDelay(3000);, T$ E' Z  m1 |. ~

  47. / G" w# U; W8 X  a% k% Q# a  k
  48.            doublespeed = 10;" v9 E  {8 j4 L- N; }( l% m
  49.            doubledistance = 0;
    6 t, j8 e4 X3 e/ k; j

  50.   N+ G$ ~9 X3 q0 t. B) N3 u
  51.            //起步加速
    $ ]4 ~3 ~: k, t) B( t' j3 l
  52.            pilot.travel(300,true);4 W  h, l7 Y: F& s

  53. 2 ?3 M+ O' S' ?" {
  54.            while(distance < 20) {+ h0 p( T* w  f% ~( S
  55.                    distance= pilot.getMovement().getDistanceTraveled();6 k0 v$ h* K0 \, _# a8 P
  56.                    speed= distance * 5 + 10;
    ; e, ?! x/ L" `6 z- U% ]
  57.                    pilot.setRotateSpeed(speed);/ C. C5 `) U; _; u9 ^
  58.                    Delay.msDelay(100);
    % s, K. b8 _; E6 Q7 Q
  59.            }0 r  {9 g" o3 F9 m' L
  60.            for(int i = 0; i < 10; i++) {
    : v$ t6 R( m- f, u$ I+ n; m2 B
  61.                    speed+= 5;
    + f% d" K2 M7 S( x1 N
  62.                    pilot.setRotateSpeed(speed);
    ; x' r; N7 P7 {! p+ b& I% w
  63.                    Delay.msDelay(200);
    " f. W: _% x; o' q( U; l- `8 v
  64.            }
    & K, D6 ]! s0 K; C1 q0 O
  65. 5 G, r) [; d' h( w3 |7 F
  66.            //TODO 减速
    ! }1 d1 i: ?  V! D3 u

  67. & r* U* c" v' r. Y
  68.            //停止机能4 ^: A0 ?5 R6 Q  {4 ?' \
  69.            while(pilot.isMoving()) {  j9 |  ?! L. V% b6 }3 M
  70.                    if(Button.readButtons() > 0)+ y! t$ {7 P/ u/ y+ [5 _6 R7 ?6 U2 w1 `
  71.                            pilot.stop();
    % n& ~5 K: M" E0 [& |
  72.            }) r% b% `+ Q% f1 Z* E; l
  73. 5 G# q! q5 b# ?2 D" }6 @& i- `
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    & J( V. z2 K& {0 k+ i; `$ v
  75.            System.out.println(-Motor.A.getTachoCount());. Z/ g4 R4 N* {) S" O
  76.            System.out.println(-Motor.B.getTachoCount());
    & U* H2 X1 x$ k" y, \
  77.            Button.waitForAnyPress();
    / y/ t% ^$ t( _  Y/ J8 J$ {* r
  78.   }+ K7 s, ~2 r/ ~( I% l

  79. : \% v# a7 e; J3 w& C3 @
  80.   publicstatic void main(String[] args) {9 O9 P# }3 D0 X% Z- j& @
  81.            Straighttraveler = new Straight();# H! P* K9 J! X" q5 w7 a6 {1 D0 b

  82. $ W8 p& p3 ]7 Y# n7 w- P' ?
  83.            traveler.adjust();
    ! H  J( f  }0 F! g
  84.            traveler.go();
    % J. a' ]0 J: p# c
  85.   }
    3 ]& V& u. k, e+ u2 z" D
  86. }
复制代码

5 Z: P' S+ U1 K2 I$ L4 p& A
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 编辑 ; T. ?; S5 I4 M; _1 K2 N. w

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

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
- f- t( ?" d! e6 m这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...
# v4 u+ j! W# ?2 j. |$ I! ?
我用的是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-2-9 21:40 , Processed in 0.512497 second(s), 20 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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