找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 11504|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
6 v0 b7 _6 j2 n& g8 S: t* K9 A
# K; w: I/ t: L3 b. }
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

( P4 ]( w: g0 b0 N3 w
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

  [" O0 S! x+ {5 t  J* c- ~6 y
场地9 k( o; h) _. e3 S( ~7 [) E
  水平度和光滑度
在家里当然瓷砖的效果是最好的
; Z* c+ O2 f, p7 k9 v4 t" d; C  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直
5 F$ S* n0 s& e3 y  ~+ u$ h, B
) R5 [$ R& p# E% M  h  w车子结构
  @6 x. e, O& Q  轮子间距
) A, L: [" v# a/ [0 L" A0 x/ R     轮子间距越大越好,稍微想一下便知% J: \& d& T  _( j! s* R
  轮子大小
: t3 _5 j; Q" j, q) V* i6 r     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
& N) z. f/ X2 H# `0 L+ \) R  随动轮的设计
/ ^: T9 R" T3 Y. _; }9 Z; K     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
; d3 V; F- d! h' G* i$ p1 `  重心位置) Z$ M* u( \  W8 t
     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小
: Z# R* {- f" W2 u' G  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
- g9 s# e' U# O! I% j  L  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# P/ s! M" {7 \4 S- Q/ o
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动
6 M" ]6 S( U$ [0 ~. I, J- q1 r  k' [' e7 w0 a# p8 V
控制程序
# `' C5 u' Q4 f( f  运动过程控制7 p% @* }1 s6 w3 ]2 g. \
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)& S; h0 D1 u4 b: |' H6 C0 H# D
) Z! f2 w4 a6 A  D; s8 f  s, q
调试与运行
% P& y3 i; U" S. R7 d2 U  轮子转速调整(车轮大小的设定)$ G3 U) d3 w! N& Z
      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法; @0 k$ X1 S# Y+ K" G2 C) L
  起始位置车子正方向和直线间的夹角
4 n3 Z* m2 {  I: Z/ n      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点

0 g+ V) {2 ?# F. e5 y0 C9 \
5 u+ q% K( ~' m9 x4 f. q
; U. n. e' Y; X2 w' o3 L4 M
然后上源代码:

  1. * c1 T) c/ {% H( t4 S) v
  2. importlejos.robotics.navigation.DifferentialPilot;, W2 o* G9 {. F- U1 ^- a: b
  3. import lejos.util.Delay;
    , F+ q  J6 d8 X) N
  4. ) r& w" y  s# H5 _
  5. /**
    6 O5 x7 B0 C+ w" d" I% H
  6. *Robot that stops if the buttons are presses before it completes its travel.
    5 H. g/ ~( ]0 P. l6 i% j
  7. */
    , c& |$ e7 M+ J" c+ g
  8. % }# a* A1 ?4 k6 N$ z* b
  9. * @- g$ M5 q( e7 ]3 o3 Q
  10. public class Straight {
    4 \2 t% R$ O% n/ y: R; E* x
  11.   DifferentialPilotpilot;
    5 H$ I( ]1 u6 U3 F
  12.   doubleleftD = 4.3, rightD = 4.3;) ~8 z) H% O! E5 t

  13. ) k" A/ t# [( F$ p2 x- O
  14.   publicvoid adjust() {
    8 r* I5 ~) H; _% G/ X0 w# O0 [
  15.            //wait for release
    % R( k; t6 w  u) I
  16.            while(Button.readButtons() > 0)
    * L# j% h3 V# C1 ^( I
  17.                    ;
    ( n/ y$ X$ ^. v( {
  18.            while(Button.readButtons() == 0) {
    ( h' T7 N6 C3 {
  19.                    //input size by adjusting the wheels) p8 f6 b6 }! p6 M' L
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;
    8 L9 d6 {5 Y% ^# X) g7 D" p4 h' l
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值, l7 ^7 F$ P$ s1 r" W% l6 n

  22. # A) r0 {% O1 ?( E' O9 j
  23.                    //display the size input5 N: ~1 k5 u$ E! S) @! o0 B" z
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);! N+ ~! w9 ^) q) n; }  I/ d" Q/ d
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);# X# @9 A% X% u/ i* {' l3 O
  26.                    Delay.msDelay(100);
    * i/ M( j' v  F* _
  27.                    LCD.clear();
    2 Q: D5 o# }1 X$ h' K
  28.            }
    $ S$ F; J" s; C: a
  29. ) Y) U- q: t; d; j( E  }) U
  30.   }% y; N. k; O6 B' ^9 s

  31. ( p8 Q: W, h( o+ X. q
  32.   publicvoid go() {. h& k) |3 ^; W# G
  33.            //准备起步: W+ w8 W8 o5 u; V; M
  34.            //wait for release
    7 ^. e( U( C8 t2 \3 X- u3 p; J
  35.            while(Button.readButtons() > 0)
    % B5 r8 L+ E7 c' V. a1 a; X0 I
  36.                    ;8 r( B. l2 o; h7 f( b( K% e
  37.            System.out.println("pressto go");) x$ Q  e. [6 T$ M7 X  @3 M
  38. ! ]. \  F# ?$ j! e; a/ B# F( [
  39.            Button.waitForAnyPress();
    % [" O9 _# a: c3 ^# w# {+ v
  40.            LCD.clear();; ?7 d3 L' \; J5 }& \9 S+ r
  41. : U" O, s  G% _4 S$ U1 Q* t
  42.            //初始化
    ' a) w+ F+ D- y
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);1 ^! t" S: V( R$ `7 U1 M
  44.            pilot.reset();4 N. y! g) W: I4 f7 E
  45. 1 y( _! j) r1 n) w; N# O
  46.            Delay.msDelay(3000);" [* r: n  g) f8 N5 g" g- M
  47. & s, `1 S9 ^6 \. g
  48.            doublespeed = 10;* u" L5 @2 q+ U; |: a; Q( d: X
  49.            doubledistance = 0;) ^( q; e# S# }' F

  50. + R9 |  ?4 c/ y( }+ w# ]
  51.            //起步加速* p7 v* f- E+ D7 @3 l0 v4 O
  52.            pilot.travel(300,true);
    0 U* P% ~% ~1 k4 I9 O9 @, ~0 @
  53. 6 ^" X6 N; h5 w+ N
  54.            while(distance < 20) {
    $ p2 b- i. X1 X$ W; j3 V
  55.                    distance= pilot.getMovement().getDistanceTraveled();, N) f% I" _8 v1 o9 T2 [
  56.                    speed= distance * 5 + 10;# I$ g: n8 K% B9 `$ a6 e! x
  57.                    pilot.setRotateSpeed(speed);
    3 ~8 l9 K; C# x! M, \. V
  58.                    Delay.msDelay(100);
    ) D, P; O- o: v  t' e
  59.            }7 |: j1 _6 n  u* r2 g: j& S3 _
  60.            for(int i = 0; i < 10; i++) {& t' `* Y) j; n/ B; t# @; _' h; w
  61.                    speed+= 5;
    , k" T6 w& X# h% P0 u" v) U
  62.                    pilot.setRotateSpeed(speed);
      T6 T- \0 I. y9 o& H
  63.                    Delay.msDelay(200);* I* X7 x$ J6 ], C. y
  64.            }7 ^- a1 f3 E4 m* o' ~! U
  65. 2 s  `  ?! Y; G, b
  66.            //TODO 减速
    6 M3 {( O2 R% W- N( i
  67. ( U# @' d6 t; c$ G% C: X+ ]
  68.            //停止机能
    * |1 Q9 Y' L6 d- c5 v, c: e+ S
  69.            while(pilot.isMoving()) {
    " E0 |1 O7 o3 g
  70.                    if(Button.readButtons() > 0)! e, L9 _- o5 _9 K2 v5 \  v; O8 i
  71.                            pilot.stop();
    $ m: k* j6 U/ V  J& [0 i3 c
  72.            }
    1 x! A, j2 d% Z& c: e; @

  73. $ a4 G7 L. C% `/ X% Y2 g4 F; h
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    / Z$ C0 D( z( g! `6 ]; l( y
  75.            System.out.println(-Motor.A.getTachoCount());& q# I" T& g' U' b5 f
  76.            System.out.println(-Motor.B.getTachoCount());
    : X! _+ O) t  C4 n! A
  77.            Button.waitForAnyPress();  Z  W( t1 M! P) b8 l. o4 G* W5 \* P6 ?
  78.   }
    % F; S' D$ U% N# e

  79. : `3 V: M, e9 k, z6 X7 d7 q/ R/ \) ^
  80.   publicstatic void main(String[] args) {
    5 v% y" D/ N% P( b
  81.            Straighttraveler = new Straight();
    6 F* N2 J" g! `% h" C' i0 [1 {

  82. ; H  E' L2 Q  U$ W7 H4 l9 V
  83.            traveler.adjust();
    2 i% e! e: ~  p3 n/ l. P
  84.            traveler.go();
    ; ]) n, m+ T0 ^2 s* @1 q4 p. e
  85.   }3 S+ |/ d$ P; k: a/ F
  86. }
复制代码
, L5 X. u) `+ {) n4 f( m
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 编辑
; V9 w0 Z8 V; q( F/ K" e0 ^# [/ u& s* K3 P* U3 O
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22+ Z) Z# o. f9 P* K- z" \
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...

' z8 K0 [4 M$ L, b9 J7 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-2 12:48 , Processed in 0.268446 second(s), 20 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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