找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 13417|回复: 7

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

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

$ @# ^& S) B  h: O: W# {/ @0 J8 ^
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

2 y0 J* k3 ^! r* O1 Z  f* V
场地* T/ N, T: |2 A% Y
  水平度和光滑度
在家里当然瓷砖的效果是最好的
8 S: T1 Z; f/ p6 B% n. S* l; N  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
5 J) o( d/ |& \2 ]
6 e: L$ U& E# c8 H* d+ q车子结构
# X: ^) g+ d; y: F0 J9 L' \7 ^1 z0 P: A  轮子间距
+ ^2 ^& K. t1 K# O/ p6 S; y8 e     轮子间距越大越好,稍微想一下便知
. E) m0 |1 A# \1 N  轮子大小) f* S% z& h9 n- d+ q- _
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
) P# j4 r7 D; ]7 Q  随动轮的设计) _% W" f, I/ p6 D6 j2 h
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
' _4 Y% I+ B; ?, X: [$ ^  重心位置
4 n, m! N: ]( }2 O/ i" |/ e5 g     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
& O% b& |9 x4 Y( R9 w: z- h$ K3 |8 I- [  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大9 X+ [/ S$ C7 ^+ B
  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)
2 ^* D4 w3 h9 B& D$ ?: _  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
6 q* q* J3 y$ M2 o, F2 N9 p
3 C  J: D) w5 y! ^4 d8 d控制程序
1 i; X, b) `' i& x7 C- }1 \2 d' r  运动过程控制
# X% e* m: M2 {$ s     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零), l" G6 j' t# o* d4 _
6 [, |& F9 B) S4 [2 c+ D6 P* P
调试与运行" L0 d9 E; \) e9 b+ d
  轮子转速调整(车轮大小的设定)- m9 k2 g5 T$ V5 a9 W2 ^( [8 u
      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
9 o# D& Y6 {; o% B' D3 L! N  起始位置车子正方向和直线间的夹角
5 g4 w2 A1 D' J2 ^7 k/ s( w      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点

. i$ z! t5 V( ~9 c5 g4 w$ A9 _- @
5 L# }% i1 [9 [, G: R! h2 [
然后上源代码:

  1. 6 B( a, T7 {# q% e9 ?
  2. importlejos.robotics.navigation.DifferentialPilot;2 X) I  N( j6 ?) z( t# i+ X9 O
  3. import lejos.util.Delay;5 b/ G+ c  l' c! t* J% k% M# v+ y

  4. , E/ Z0 a6 l: _7 c
  5. /**. b8 [8 y1 ?! r/ v
  6. *Robot that stops if the buttons are presses before it completes its travel.& T+ ]& D( G7 N+ A! @! Y
  7. */
    - v+ r" [# \5 ^, w/ J' h
  8. " k6 \8 x3 a& @9 ?/ i0 i  s
  9. & _5 J* O1 r: `" |" w
  10. public class Straight {* d4 g% j8 L/ {# X
  11.   DifferentialPilotpilot;+ v$ K' s$ L7 N6 H7 y, u" u! A
  12.   doubleleftD = 4.3, rightD = 4.3;8 k. s8 U" S8 S) W3 T

  13. , `! T) ^7 w4 p" v: \! R/ w4 I
  14.   publicvoid adjust() {4 _2 L: U! B! y. g5 _8 N
  15.            //wait for release. p2 Q; u; f" _8 ?
  16.            while(Button.readButtons() > 0)
    6 S/ u% g. P/ s# l
  17.                    ;
    : G8 k! k, Q7 i0 m' D. q4 m' V' g
  18.            while(Button.readButtons() == 0) {
    1 r& X) L5 |9 B/ q3 a! q. ]. U
  19.                    //input size by adjusting the wheels7 {% m+ W4 d* ~% m' Y" y
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    " o" w6 ~, i# d3 t, j
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值$ V8 d: }% ?# o7 o- o0 J; n7 B* n

  22. $ R. Q: t1 w  w1 F- F
  23.                    //display the size input
    9 O5 }* F0 M4 d" T
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    8 I6 V! T2 Z' S' f' n3 }# q5 F( B
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);- W. }+ s4 \4 \9 B' B9 B# p
  26.                    Delay.msDelay(100);2 _3 t% L% S& ?- n1 n" C- o; A
  27.                    LCD.clear();7 a# Y# o& G. K6 W8 ]. `! r' f
  28.            }4 W. Q% L3 z/ n. F$ u) o  F
  29. 9 U! s' Z  q( Q1 S* ?) s, E
  30.   }
    % W0 J7 V% v: X5 s* M0 s
  31. * m" k* ?& F4 U, b8 J, w. \7 G
  32.   publicvoid go() {
    5 J- U$ n5 T; b8 W0 ^
  33.            //准备起步
    6 A$ k0 Y8 N3 g2 m0 p& G) N5 x
  34.            //wait for release2 U- F. b4 P. t0 O
  35.            while(Button.readButtons() > 0)
    " }+ a$ Z/ R7 E
  36.                    ;
    , q- F8 ^! H0 J- \
  37.            System.out.println("pressto go");9 D* J  g4 |5 Z0 T) ?2 G
  38. ' p. i5 A2 @/ m- Z  D( R
  39.            Button.waitForAnyPress();! K" ~6 H' z7 e! G
  40.            LCD.clear();: ~7 I$ z. L8 v) i6 C7 K0 c& x
  41. 6 c- b4 G" Y) z4 d+ O0 l
  42.            //初始化# K* Q6 e1 ~- u, p4 H
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);. V$ [/ b# z/ f! T6 x
  44.            pilot.reset();
    & g6 k5 ]0 [+ o, X

  45. 3 d. W& p9 v6 n
  46.            Delay.msDelay(3000);7 p$ t7 X+ Y, t, \/ c! ]
  47. ( t0 `5 Q+ k9 G8 z; v6 b9 j
  48.            doublespeed = 10;
    " ]0 F6 {* {- E& }$ ^) b. b7 X4 s
  49.            doubledistance = 0;. d) |: r- E  b9 r+ E
  50. 4 M3 O$ l* b1 x& U; ?
  51.            //起步加速: C6 l4 K! C; w$ ~$ a6 P8 D! {
  52.            pilot.travel(300,true);* f8 b* c, g! m! D- O- D
  53. 1 a$ j  n& M. w- G3 ^# v
  54.            while(distance < 20) {
    ' ~: `3 k- V# ~4 V1 z
  55.                    distance= pilot.getMovement().getDistanceTraveled();1 |4 d. r2 k! H  T" _/ v* u
  56.                    speed= distance * 5 + 10;" S1 K$ j/ \4 e+ _' b$ N
  57.                    pilot.setRotateSpeed(speed);
    ! z' A+ u7 s% `) F6 b& O7 g
  58.                    Delay.msDelay(100);
    & {2 Z8 ?) B! v8 Q2 u3 `
  59.            }- u' k* R# l3 H9 V6 S  Q
  60.            for(int i = 0; i < 10; i++) {; e! {: W8 J# C/ c2 {, A
  61.                    speed+= 5;! d& e2 F. b; h) O' z/ M, @; G$ o
  62.                    pilot.setRotateSpeed(speed);
    $ t. y4 d- C1 f9 G! u  z! c* w
  63.                    Delay.msDelay(200);
    7 `6 Q7 r. Y8 C: q- H5 i. ^
  64.            }
    - U+ U" {+ ^4 g) K; R" L

  65. 2 c9 s# K! P* k1 Z0 _( a, S
  66.            //TODO 减速+ G+ K6 z; z8 C- V6 p

  67. , r0 e3 ^1 N* L0 o' E
  68.            //停止机能
    " N! I  ~; h. X, K, A: B
  69.            while(pilot.isMoving()) {
    2 x- K1 S0 O% G, b
  70.                    if(Button.readButtons() > 0)* n& Y4 x$ @# F# q4 U
  71.                            pilot.stop();& C2 I  @7 u0 r4 i. X; N( Q: I$ @
  72.            }
    $ }& g9 N2 S5 F( x

  73. 1 z; r: L# K% L& H7 V* R' s
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());* X$ n0 i- H8 n5 T
  75.            System.out.println(-Motor.A.getTachoCount());
    ) M& a4 ]7 U! c5 y
  76.            System.out.println(-Motor.B.getTachoCount());
    % Z% \; W. Y* Q# e- W% H6 T
  77.            Button.waitForAnyPress();
    8 \. z& a, J3 P- N8 u8 U- g
  78.   }
    : ?7 G9 _7 I8 y% T( T; `
  79. 7 o' K* k4 W9 w/ y7 x" X0 ^
  80.   publicstatic void main(String[] args) {8 m& p; N% P2 O# a9 \% k
  81.            Straighttraveler = new Straight();( F- A; j( s8 C& D( ^+ C

  82.   J3 `+ ~: A2 i9 b7 J1 b
  83.            traveler.adjust();
    3 W. V( X* u- p1 ]
  84.            traveler.go();% o8 f; m6 Z% @7 S, s. {* W
  85.   }' S4 {: {6 r7 U4 y0 |, O
  86. }
复制代码

: ~" K( r0 u( K- o$ F8 _
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 编辑 # l# Z6 o' ^% ^8 G) y
$ ?- o* u% t$ n7 V+ Y
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复 赞 踩

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
" [8 l' f7 h3 j! z+ T! x; Y- o这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

2 z8 ^, Z9 _* X我用的是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-11-11 05:14 , Processed in 0.039632 second(s), 26 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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