找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 13124|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
/ B+ G# {, Z7 t% j. F4 X4 T& g
2 j2 I3 p4 F5 J! L2 P2 f( ~6 {+ H
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

9 X. y6 N% y2 u3 V# J
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:
9 I" l' O8 c# P3 U% I% E& \( j
场地* @# N, W! I3 P1 g
  水平度和光滑度
在家里当然瓷砖的效果是最好的. T3 p4 k: B) e+ h0 R! O6 L$ Y
  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
7 j. z& p$ [# o9 e" ^0 x
! s  `- _: Y+ `+ ?3 s车子结构
+ B, z) d8 J6 @' U/ S1 r2 @  轮子间距) z( S' y( Q' a% c* u6 m& x
     轮子间距越大越好,稍微想一下便知7 z/ b: j2 f9 ]: J
  轮子大小* R, S2 B4 m9 c+ U6 p+ K0 p
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)2 {" t1 Z- o6 L% O* S0 U
  随动轮的设计
% y& w% A  p3 G, Y; Y# q     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响, H) D( K7 I! ^+ ^6 M& O
  重心位置
/ F, ]# Q- A  L, H; \, o9 e6 H     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
' N8 Q% G1 f. [1 c# P  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
) z, C4 g2 [& D9 p  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)' V! Y% I% Q$ ]
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
# b2 `$ J. |2 e; P! t$ h5 \' J: A, S/ W+ ?/ ~# Y4 |& @
控制程序, k* K5 J3 D) _1 e, ]
  运动过程控制
  h5 Z( Q. O% h     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零). Q. m' l1 j8 Q" D- Q. a

0 l. {8 \* O9 y( E调试与运行- Q7 F% R  o/ Z+ a6 Z6 F4 X
  轮子转速调整(车轮大小的设定)' u) G3 q7 C/ Q- p
      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法" B. O! d3 E/ |& b* M
  起始位置车子正方向和直线间的夹角* b% j# i" `2 q  u$ K) x
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
( Y7 }& H$ a6 Q, g8 n; X) D
# L5 D- `5 k/ ?/ ~7 j1 K$ r

; H; k/ e. W' b0 O" y; ~$ [7 [* N* |
然后上源代码:

  1. 1 R9 \  E8 i9 x- s7 n5 u
  2. importlejos.robotics.navigation.DifferentialPilot;
    6 `0 H: C7 Q  _8 q- ]
  3. import lejos.util.Delay;
    - C: w" g% s" E6 \/ I. i; q
  4. ) p, o5 O; m: \* X
  5. /**1 T: A4 _1 C7 v4 p3 e
  6. *Robot that stops if the buttons are presses before it completes its travel.
    ' e! l1 N# f+ [! O! |
  7. */
    ! F% T$ F& D) x
  8. 7 N% A6 l3 h* l+ J: x7 r- ?) I% p
  9.   P4 \1 q0 o9 D% B& t
  10. public class Straight {  C8 Z7 [6 @/ N( e& [/ ], |( F
  11.   DifferentialPilotpilot;
    3 E' x% \' Q' |/ H+ t
  12.   doubleleftD = 4.3, rightD = 4.3;3 I. P7 ~$ W1 l5 M  \

  13. 5 O1 Y2 g: Y0 O0 c4 r8 I
  14.   publicvoid adjust() {
    . b/ r, |7 Z* t' G/ x0 c
  15.            //wait for release
    / G( D3 T7 i2 _7 ]
  16.            while(Button.readButtons() > 0)% v! U* x# H6 H
  17.                    ;+ e2 Z# j+ h) Q1 h" K+ X
  18.            while(Button.readButtons() == 0) {
    % m* G1 M" P+ s' `
  19.                    //input size by adjusting the wheels1 N: ?) |4 \& M6 f1 `  r. C
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;/ h+ H& H1 A4 x
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值* Q& {9 O# F+ ]8 M

  22. 3 ~4 `/ P. q( `! X1 f; {' h6 L7 L  B' g
  23.                    //display the size input
    / H' A. F1 a# w' \
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);- s$ X4 O$ e4 a2 [7 M& P  p
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    7 Y3 }3 |# H  J$ {& o& t' y4 I
  26.                    Delay.msDelay(100);
    ! l( V3 ~0 ^6 h0 f
  27.                    LCD.clear();. x+ R& |5 f9 [4 Q5 B6 P2 X) Z4 o, e
  28.            }
    : ^2 `) C6 r! S" Z
  29. 8 y2 b: V$ V+ e+ ?' c3 f  [
  30.   }
    , R2 |; U. \( K1 ~1 y
  31. . S4 S0 Q: M" s$ `
  32.   publicvoid go() {
      N% J9 _+ A4 C" O% F4 r
  33.            //准备起步
    / k' w' ]$ a( C; d5 a2 C  n* S
  34.            //wait for release
    ) A1 Z0 S% x& M1 r7 X, ^" y
  35.            while(Button.readButtons() > 0)
      |0 R( _" Z, r! ?( j) m: K& e
  36.                    ;( {; k1 f: O  F9 F/ F) O* T
  37.            System.out.println("pressto go");
    * j6 o" v( n% U* M9 x7 M  @- G6 x

  38. ' }6 g* {+ B) x# ~7 W
  39.            Button.waitForAnyPress();
    " K+ H! @+ k  d; T# A" Q: ~0 X, V
  40.            LCD.clear();; A8 ?/ C- G+ ~0 z2 _

  41. # b* J6 F4 }7 \1 k3 h, x3 G
  42.            //初始化
    ; u  h* \3 S9 c2 d- {3 {  E/ C
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);7 _' X7 {' m* Y* C; J; f
  44.            pilot.reset();
    : S' n: C0 Y2 @/ w

  45. % P. l: D5 K5 h6 S! B" z) i' H7 L
  46.            Delay.msDelay(3000);* S; ~. [' _4 r# u
  47. # S4 P  S+ E  G2 _; |. t. g
  48.            doublespeed = 10;
    ( Q& U; ^: C& _! b( L
  49.            doubledistance = 0;
    ! c' @2 W2 O  p" g1 k% v
  50. 5 `1 F! }2 g0 C3 q! A, T
  51.            //起步加速
    % m2 }  D4 ]: S7 s$ L3 x
  52.            pilot.travel(300,true);8 V# X; h, b: i6 z* I2 Y

  53. 3 W- L- S7 S: |% z2 z3 l
  54.            while(distance < 20) {& x9 q  J/ G$ B3 ^6 p% P2 A$ s
  55.                    distance= pilot.getMovement().getDistanceTraveled();/ x! ^: }9 P" `: U1 N
  56.                    speed= distance * 5 + 10;- B  }3 x3 y; P! E7 k
  57.                    pilot.setRotateSpeed(speed);
    9 i8 F* m) |( U' s) m! A
  58.                    Delay.msDelay(100);
    8 `7 I7 @/ J2 r: Z6 e, a% E
  59.            }) F$ j% r5 k/ k1 }+ ^% [4 c% K
  60.            for(int i = 0; i < 10; i++) {
    . I. t7 I# `( y
  61.                    speed+= 5;7 |( t7 {( R$ V" e7 J$ O0 P
  62.                    pilot.setRotateSpeed(speed);+ |% b9 r0 w& S/ B' r" h' V
  63.                    Delay.msDelay(200);
    + w$ \% U# O1 o# f5 z8 H; L
  64.            }
    ) I! {6 u9 P% [* Y
  65. , s2 e1 I5 z& @# S
  66.            //TODO 减速/ |( U2 ?2 i' A* V" W' S  |
  67. 3 x9 y, S8 @$ W( N! y9 o
  68.            //停止机能
    - v+ n7 r  ^& K; T1 N
  69.            while(pilot.isMoving()) {
    ; o" _/ W# i$ N6 D
  70.                    if(Button.readButtons() > 0)
    / N3 N" P" D7 _0 @% B
  71.                            pilot.stop();( a+ {) \8 A. h
  72.            }$ a4 q$ r! @8 |# j
  73. 5 o6 m+ ]. d& _; s4 {
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    ! M- u% l! A* F" i
  75.            System.out.println(-Motor.A.getTachoCount());$ Y& @3 y% D! S% Z( b
  76.            System.out.println(-Motor.B.getTachoCount());
    $ F  \0 ]6 z) U: o% B5 U
  77.            Button.waitForAnyPress();
    + m  S2 ^7 L' |0 m
  78.   }& Q! @3 M- y# n$ t
  79. 3 N: ]9 [+ e; @+ m" r/ _
  80.   publicstatic void main(String[] args) {8 @; a1 y3 g5 S
  81.            Straighttraveler = new Straight();
    7 W2 W' f' U: r* R) A9 n
  82. 6 {9 m4 j% Y/ A7 V' O. M( X
  83.            traveler.adjust();% u8 e4 ~& Q2 A- n) x4 s
  84.            traveler.go();7 X7 R# u3 W2 Q1 e0 d( P
  85.   }
    + a. z$ k( V$ }* g6 z7 s
  86. }
复制代码

3 X) y* n; o' e8 n
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 编辑 0 i/ E7 t# a5 {: U& V9 {7 }
7 v# p) \1 f7 c. F9 N
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
4 g0 K  F( U/ E+ ~这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

8 |' _8 Z; P. R- g# b我用的是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-9-23 13:00 , Processed in 0.470634 second(s), 19 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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