找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 10513|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
$ {6 o7 E1 F( B7 i. D/ g
% c8 ~5 M% A' H
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
+ O5 U6 R  k" ~- A
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

+ \( N1 d+ f2 D* E! i/ `% ~
场地
; c, {( W- s) `: |  水平度和光滑度
在家里当然瓷砖的效果是最好的
' Q3 Z* a5 s2 B- R0 e. [1 A  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
1 D5 I7 e- U8 L. d" j- d, d% e+ I; m: P' l4 a7 x. E8 i$ t# o
车子结构
( N8 D: ]1 p& ^  x( {" g  轮子间距
' {# F: A# Z- v* K     轮子间距越大越好,稍微想一下便知, W2 h% O. K  N& S+ ?7 ?; z
  轮子大小
5 O7 m1 Y4 l* [8 X2 t' M     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)" l3 I% j  A% c1 [) m8 y
  随动轮的设计
( ^5 ^$ ^* p  D0 w9 ?: ^     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响" X- p3 }# D9 y
  重心位置
( w, e7 J- A2 }     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
( W7 m$ C; v! y& j, K' q  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
; H+ U5 K" l. }" e0 x# }+ D  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
1 T! d& F* r: ?( \6 M  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动- x' C5 t; l" f% ^
7 w: ~/ s, C5 U% @8 v$ r
控制程序! A/ T0 j# H5 D3 K
  运动过程控制* O5 \9 ]0 r* ^; {( M
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
1 |' N8 Y6 r3 E8 O. L/ @& J; F; c
+ Q, C- x" ^& s: `' R# h调试与运行
( ~% _6 v. \$ F5 a5 V  w; H- g  轮子转速调整(车轮大小的设定)
) {1 X. R7 Q+ W+ E( _      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
% j) z5 o! w. |8 {; K  起始位置车子正方向和直线间的夹角
! w* x% G7 J, g/ N. S      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
* q4 N) _) Y+ [, X
4 ~2 k( q+ W) y) X

4 z& b8 i" [, M8 ~* f( M; E: e7 b
然后上源代码:

  1. , d' A9 S0 X" A3 I* R
  2. importlejos.robotics.navigation.DifferentialPilot;
    + ~; ~* I( u- F  v' W- c" U
  3. import lejos.util.Delay;  o% L6 e* n( e9 ^
  4. ! @2 x( l  p5 L& g
  5. /**0 x( ~  o+ {; x' h8 W
  6. *Robot that stops if the buttons are presses before it completes its travel.
    ' M) B6 O. q: b0 c! ^8 [* A, C
  7. */
      ^2 h* c& U& ~+ e/ f6 E
  8. 0 u0 L) ~) v& J5 f; \
  9. % b4 P) c( q6 J- \" Y
  10. public class Straight {
    0 t8 G1 L6 w* i' v* r
  11.   DifferentialPilotpilot;
    + ^8 F3 ]( x! f! H$ V8 K" w& Z
  12.   doubleleftD = 4.3, rightD = 4.3;# H8 \: k. }* [6 o: O" N3 X0 d9 \* V
  13. " G+ ^# p  S4 p* W3 u3 B
  14.   publicvoid adjust() {' [* a6 j& S8 `5 n6 B, |  J& Z
  15.            //wait for release! ?6 H3 V+ I0 h( s, B* n
  16.            while(Button.readButtons() > 0)
    + E$ m# }5 \& u" y4 q7 @6 G
  17.                    ;$ L6 H* c" p) a" g
  18.            while(Button.readButtons() == 0) {
    * I& w$ F+ [" E+ K6 l+ ?$ T: d* l
  19.                    //input size by adjusting the wheels$ E- ]  N  }3 e
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;4 I) Y: V# L+ Z; y
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值. o+ j# ]2 s1 ?0 r: G; [/ |
  22. 2 Z( b- ^2 n2 K& A/ e) Q# U
  23.                    //display the size input
    3 _6 @" i- A- \% ?$ r, R1 Y
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);& O, Q0 R- H$ r
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    0 G/ F) K0 E, c2 s+ d+ H, u. f8 L
  26.                    Delay.msDelay(100);) A. A0 B6 f2 m4 W7 Q/ B* G& B6 P
  27.                    LCD.clear();
    3 G1 ?& O! g2 j6 ?' s7 T$ _
  28.            }
    " w) R# D& D/ U  j
  29. 4 B6 U& R3 G+ K# Y" I
  30.   }$ L5 J* B  c$ [. k" C

  31. 8 i" A& V# y( H' N* D
  32.   publicvoid go() {
    7 S  X8 I0 T6 U7 S8 ^* T7 C$ r, G; V
  33.            //准备起步. N- F$ x0 B8 U. {5 @
  34.            //wait for release
    + ]; _6 }% R7 i' w' \( I- F
  35.            while(Button.readButtons() > 0)+ x4 P  x- o* x; f$ d8 B7 y8 x
  36.                    ;+ l: O( a' q1 l, Y. H; b5 |; Q* V
  37.            System.out.println("pressto go");  s3 k) e3 P  [5 Z$ w
  38. 2 c; [5 |4 E% e6 @. c4 W
  39.            Button.waitForAnyPress();% r: }4 l7 R7 i1 ?
  40.            LCD.clear();
    * p* B2 s$ l' R. S. P, z) u: l
  41. : m6 ^: ~+ g8 Y1 |& ~: }& i
  42.            //初始化1 g7 x* K  p9 Y  s7 K# h& H
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
    8 g2 n" [% I! Z5 B5 @' R, j% d
  44.            pilot.reset();" o* G# U) Q% F, j
  45. % j! i' [7 K3 e9 W
  46.            Delay.msDelay(3000);" n( W( K7 C4 f

  47. / G9 v& G, C# t7 Z* O
  48.            doublespeed = 10;
    : c' n9 n( v& {' p1 V5 K- p
  49.            doubledistance = 0;3 r; ~4 S" R9 N8 n7 [) m
  50. : m8 c) v0 x! c8 \$ X- J5 e
  51.            //起步加速3 _( h6 v; q- d9 ^3 @( t' o5 k4 b7 m7 m, g
  52.            pilot.travel(300,true);
    5 W* o7 F; V  v- H" b
  53. 4 ^( ^8 Q; ]& D4 }4 A4 K
  54.            while(distance < 20) {
    4 H, u1 X# T" e3 i& [5 x
  55.                    distance= pilot.getMovement().getDistanceTraveled();; `( V0 P& F. y5 i
  56.                    speed= distance * 5 + 10;
    3 q2 \$ N" Z/ p
  57.                    pilot.setRotateSpeed(speed);
    4 w4 h, |/ ?1 C0 o, ~" o7 L
  58.                    Delay.msDelay(100);0 P5 u( ~; x0 n- Q% g
  59.            }
    ) b+ \  U9 [  X) W; I
  60.            for(int i = 0; i < 10; i++) {
    1 b  f$ U( B& `) O4 Z3 C
  61.                    speed+= 5;; a0 h9 q: g' W* ?, w
  62.                    pilot.setRotateSpeed(speed);
    1 x- |5 F1 h$ ]3 D, Y$ d: _$ s
  63.                    Delay.msDelay(200);
    ( ?. ~1 c- c% k( a) V
  64.            }
    . g0 s- j# P8 x0 O! T
  65. 0 I9 N3 i( b$ m
  66.            //TODO 减速
    ' F% f0 B5 T) }$ Y9 P' k
  67. 8 y- k; h3 a  c2 o! v
  68.            //停止机能5 o9 ^! e9 V& K8 ^$ G
  69.            while(pilot.isMoving()) {
    ' t- Y1 T% \5 s) E
  70.                    if(Button.readButtons() > 0)6 q! j' @5 v0 b& C3 M" X
  71.                            pilot.stop();' F( `7 w( O; T4 i
  72.            }$ P* Z4 v) x! Q* o. ], e

  73. ! {' N2 G/ Y* H
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());5 S* j8 _1 O; q3 t7 v1 c# G
  75.            System.out.println(-Motor.A.getTachoCount());
    7 F: x& Y) t& M2 Q- a9 w: V. M% r
  76.            System.out.println(-Motor.B.getTachoCount());( z5 v8 R, }# r' X
  77.            Button.waitForAnyPress();& E* r/ E! q2 }* u& i( u
  78.   }4 `' `' l% D4 D8 A. x$ Z

  79. 6 K' y* d. e1 g1 s0 {
  80.   publicstatic void main(String[] args) {
    4 I1 X2 C& a# A2 a  P- S2 h. W1 J
  81.            Straighttraveler = new Straight();! L8 D1 j' J. n* V3 z; _' z

  82. : R! g, l6 q; c$ K) f
  83.            traveler.adjust();% e* |$ Z7 o( w
  84.            traveler.go();) B1 W2 D; E6 H+ O& P3 T) O
  85.   }6 u# [. O- T& Y3 Y, |5 o# G
  86. }
复制代码
- M) }* X. k4 a' m4 K. E" {
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 a! j5 |* n  F

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

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:224 ?  R3 M+ }2 Y4 K( F0 X
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

0 |4 z8 o/ z+ d9 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-4-27 04:49 , Processed in 0.181536 second(s), 21 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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