找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12279|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑 + {. D+ k$ Z6 @6 w: m" P5 S/ w" J
9 T, ~# j; Y5 u3 P
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html
. p4 s( s) o. d' b) d5 `
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

; [: x* I' ]! E+ O) s" r- D
场地) A2 X4 J4 t- p$ q6 K- p' w
  水平度和光滑度
在家里当然瓷砖的效果是最好的! |' n0 O5 f# g$ _- m* r- I8 T
  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直+ F/ C. n' [# F6 G" s

4 e& y  n; l  r5 @& D' z车子结构) j6 ~) Q6 C4 w9 u
  轮子间距0 K8 e* u" m$ r9 e8 C% M+ ~
     轮子间距越大越好,稍微想一下便知1 {) Z% B4 `% N* U
  轮子大小
$ k4 K& B  _* K% h6 J! @# W5 V% ~     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
; r6 P! L+ o! S. E3 h0 Q  Q  随动轮的设计8 `. `( Y: y, R$ g  _( g
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响! m: I# c6 X, r$ d
  重心位置- T. `% x9 I2 \
     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
' F  }4 B% l1 g5 K  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
" p* e' b" j  f7 m' v5 ^) @: i  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)$ M2 {  O+ n5 }) x8 w# B6 D
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
. S7 [, t% C2 t# U9 T% i; v6 o% M
7 c' [, e/ R( `3 x% x控制程序5 E# i3 _- d' n$ e* q
  运动过程控制- S3 s. P  J+ t% Z/ b
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)' m2 i+ N( i+ B5 L" x
6 y  y4 N9 c5 x' w) D# a5 b
调试与运行' r4 R1 M0 x/ n5 H0 ]
  轮子转速调整(车轮大小的设定)+ x% L" o" O! p
      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
4 ?* w" i4 s2 p! `  G9 A& R: J& @  起始位置车子正方向和直线间的夹角
* D. [3 z* D' Q+ |      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
) K+ V% r; K* y: H1 I
) z" R, d( c. @7 c$ J

7 v1 |2 ?( \3 u) j
然后上源代码:

  1. , s# c8 j4 G) d. [5 }
  2. importlejos.robotics.navigation.DifferentialPilot;8 Z2 V, Z0 c- E) L5 O
  3. import lejos.util.Delay;
    9 V# o# k1 y6 l( b8 d
  4. . c6 _6 ?3 K. d( l8 ^1 C
  5. /**: `7 @' z# D5 I; q. f7 I
  6. *Robot that stops if the buttons are presses before it completes its travel.0 Q4 x% v; e: S3 V) b
  7. */* G7 T+ S1 |- a" s1 R- b2 N

  8. . h4 `/ S' _* }5 Z& L& d" y+ T

  9. % [" n+ {( Q! w! {9 ~: j- d" F: B
  10. public class Straight {
    + O( W. S0 L" K4 D4 F
  11.   DifferentialPilotpilot;: ?% P2 d- g0 n7 N: p  I
  12.   doubleleftD = 4.3, rightD = 4.3;
    " l+ E/ Q( Z: a" D) k6 }
  13. ; O6 G; K+ o. h
  14.   publicvoid adjust() {' H8 q( {( `" n: f8 g7 ^  F
  15.            //wait for release
    . Z. e4 R% @3 h+ I  r: ^# d/ l
  16.            while(Button.readButtons() > 0)
    . o( ]. a- U! c9 @6 Z, R
  17.                    ;
    " j; U. s, V9 n# A
  18.            while(Button.readButtons() == 0) {0 a1 M* A/ g9 `% Q; B/ s
  19.                    //input size by adjusting the wheels
    0 x9 k( p# H9 }0 P) }  z
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;/ M9 l/ A- f0 O
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值+ f3 z3 K/ G2 j/ X
  22. 4 f8 T3 y! j5 I1 ?! A0 v! {( B
  23.                    //display the size input
    ( V0 x. a: m7 ~  f0 p* h
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    - H3 O: |0 h! ?6 ]& Z4 E8 M
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);% d& ]! ^1 `( p. m' t' d
  26.                    Delay.msDelay(100);! m8 q( `% ?, u+ R5 P; h
  27.                    LCD.clear();8 I6 @1 O5 w) C) o4 l1 S. n
  28.            }5 z: a! h/ G! S  P& c& |& C
  29. - B+ _+ P9 }. X* N" t9 ~) v
  30.   }4 P4 x, \/ Z" O# H# a5 M! R

  31. - c2 C2 i: L, ~8 f: ~! e
  32.   publicvoid go() {
    5 y4 l- v; i) Q( j
  33.            //准备起步  X- _. B9 P$ ~) K2 S
  34.            //wait for release
    + a0 v3 g% a4 j. }9 u1 R; b
  35.            while(Button.readButtons() > 0)4 q3 w2 t/ f  |! \6 h3 T
  36.                    ;
    . X4 K. N6 A2 Z! H  B3 l
  37.            System.out.println("pressto go");6 L/ E7 x" N8 v' S7 {2 Q; r
  38. ' R  [  f, e) d2 ?1 r. j
  39.            Button.waitForAnyPress();/ m: m. P1 H/ P9 g  u0 q' a2 V7 h7 c
  40.            LCD.clear();
    * h" B3 k; |* V" z& O+ w, W
  41. % \4 ~# d. [. q/ q
  42.            //初始化& H# W) M6 H5 @: J& C
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);
    5 r/ r7 G- ?: `- `6 x
  44.            pilot.reset();
    3 O$ A( Q+ Z* H$ e% x! A! G

  45. , B1 L" S5 w7 r  r& N6 z, Y
  46.            Delay.msDelay(3000);
    ; J7 j  k+ [5 H! V/ n
  47. 1 Q# H+ \  U% ~4 [; c
  48.            doublespeed = 10;
    ( N# C4 X8 a3 T3 f# i, q
  49.            doubledistance = 0;" V; K2 v$ ?, f& a- H; S- d

  50. ) p$ [. j9 }! W
  51.            //起步加速4 d$ Z6 L' E* L& m- m7 x
  52.            pilot.travel(300,true);; O2 X; W/ @8 E

  53. 9 j$ [( C7 q3 t4 I: c) v5 T, p
  54.            while(distance < 20) {
    . a: c# H4 r. z/ s; c% Z) E
  55.                    distance= pilot.getMovement().getDistanceTraveled();
    4 t  ]; o8 o1 i0 t5 a+ x: g
  56.                    speed= distance * 5 + 10;- I7 A% T2 ?; W7 X1 k$ S
  57.                    pilot.setRotateSpeed(speed);! p5 h- b6 e- \5 j, H- O
  58.                    Delay.msDelay(100);
    ) z: O4 P; B6 r2 i* j$ z
  59.            }
    * D/ H) L' O1 g# P: u
  60.            for(int i = 0; i < 10; i++) {# {  O2 \- w( l* [* i
  61.                    speed+= 5;
    ' v& }4 F3 F! s" J
  62.                    pilot.setRotateSpeed(speed);5 r% r$ h) n, `$ g1 y
  63.                    Delay.msDelay(200);
    & D) w$ y, D. ~( c. I
  64.            }- s$ Z" U% \) o; ^' k

  65. " G6 O2 w4 o6 L. \0 `+ e
  66.            //TODO 减速
    - X& l: w( B! ~# A) l
  67. 0 `  l5 _! T, b6 X8 `8 Y& U5 b
  68.            //停止机能$ @8 M4 M. m) f+ `, l2 |: S! Q
  69.            while(pilot.isMoving()) {  E5 N3 n/ N* p! y. B, {
  70.                    if(Button.readButtons() > 0)
    7 G8 M) D1 s6 \1 V9 o7 W& z- g% }
  71.                            pilot.stop();5 G7 F/ C9 ?# h/ I
  72.            }
      D& Z: C/ k; h/ }  y6 z+ ^

  73.   F) z0 b8 `( n+ {; G( Y1 n. a
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());: Q$ s- L9 P7 V$ T2 A$ Y+ S
  75.            System.out.println(-Motor.A.getTachoCount());, [$ J/ J" j; u; Z+ Q5 C
  76.            System.out.println(-Motor.B.getTachoCount());2 c6 R: g; S- @9 @
  77.            Button.waitForAnyPress();9 t- `% n& g5 b5 A+ A! W, [( {
  78.   }
    7 M6 [2 \& B& ^8 }! o, m

  79. 4 U1 F( W& S7 `0 p! Y5 B
  80.   publicstatic void main(String[] args) {
    ) b* c0 d7 z2 ?) l) k1 }' ?
  81.            Straighttraveler = new Straight();
    / c0 ^0 B' o5 a! t, S
  82. 4 \; o+ E+ q: l1 D: H+ J% d
  83.            traveler.adjust();
    # y# f3 i5 n) s* ?( r2 X. K
  84.            traveler.go();
    , A# h# _1 B" I4 E+ t$ `: H6 `
  85.   }
    8 [( ]/ [" I% v
  86. }
复制代码

: b0 X0 D+ A3 H: q" ]7 x/ ]3 |) 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 编辑 " b& [$ f, u7 X# v
4 L0 m8 a9 d$ P/ W1 l4 N; d6 M9 ?
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22/ `4 T. L1 Y4 Z8 C6 y/ v  F) h
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...
3 v8 N  _: q* z1 i2 J
我用的是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-10 10:00 , Processed in 0.388977 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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