找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 10763|回复: 7

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

[复制链接]
发表于 2017-7-25 22:09:23 | 显示全部楼层 |阅读模式
本帖最后由 hello怪 于 2017-7-25 22:24 编辑
- l$ p2 t. g. v3 M+ m
( x$ z1 B0 W% a, A5 w7 K# ]# t
(视频里面最终轮子与黑线的距离,都不超过6mm,最小距离只有2mm。虽然也有运气成分在里面,不过就结果来讲已经很令人满意了^_^)
优酷视频网址:
http://v.youku.com/v_show/id_XMjkxOTU1MjEyNA==.html

+ I! z/ ?+ n0 g/ `7 e
首先说说车子的设计思路,希望也能对大家有用。我想到的影响车子走直线的因素有以下几个方面:

$ O+ n* J9 K( A2 G* C. m
场地; f9 W' h* g7 |% ~& y
  水平度和光滑度
在家里当然瓷砖的效果是最好的# n, |% l) D3 l
  线的直度
虽然规则里说起点终点之间不能有黑线,但是因为没用光感,完全是开环控制,所以也无所谓了。这里就直接用了瓷砖上的黑线来说明车子走的直不直: h- ?" |: D9 s3 d& u' r
: q6 c" R5 w: C! O
车子结构
* T4 j2 n0 L, m0 G  轮子间距3 z, I. V* p6 i  ^5 B, {2 Z
     轮子间距越大越好,稍微想一下便知6 b. w: ~0 ]+ Z8 c
  轮子大小, T' b7 }% r6 _2 U
     轮子直径越小越好,而且轮皮要尽量薄(我这里用的是nxt自带的轮子)
; o; M) `; [, k. b2 g- \  随动轮的设计* i! E7 I. E5 @, X  x5 X  `4 d& w
     随动轮转动时对车子的影响应该尽量小。这里我自己想出了一个设计方案(当然我觉得别人也用过),让车子几乎不受随动轮的影响
$ V; y, w! F0 \* m4 N  重心位置
9 A$ Z7 K' o* D! Q% _! W; u     重心应该稍稍靠近主动轮以增大主动轮的抓地能力。但是太靠近的话就会降低车子的稳定性,并且升级空间较小  Y( W& @' [. [0 H' @, \+ D% v; F
  结构稳定性
不用说,肯定是越结实越好。但是不能造成重量过大
0 H8 Q2 P* Z% c* b, w( j$ I  轮子个数
有三种方案:平衡车(独轮或双轮),三轮车,四轮或以上。虽然很想做平衡车,但是无奈暂时不会用陀螺仪。四轮的话转角不好把控,而且结构复杂,所以就用了最简单的三轮车。(另外,我个人认为不能拐弯的车子就不能叫车子~叫火车或者轨道炮比较合适。。。)# e3 w% a5 f  b2 c4 d
  驱动方式
这里我选择了直接由马达驱动轮子,不经过任何齿轮传动,一种简单准确的方式驱动) t0 r+ U, \0 @0 U" W
% T" |' {; h  T3 }# \
控制程序
! z; V8 h9 s" p  运动过程控制+ \5 v" R* j" f; T, f
     好的程序应该使轮子不打滑,车子运行平稳。由此采取平滑运动的控制方法,让车子开始时(近似)匀加速,直到速度足够(160度每秒)。在开始时,加速度甚至更小,可以参考我的程序(加速度增加->加速度不变->加速度为零)
) m1 {( V& D/ x) N% V6 K( P' N0 u  H% N7 }0 @' O, P- {
调试与运行, D* J2 t5 x. c3 j* p( |. W  a: r
  轮子转速调整(车轮大小的设定)
1 U( a9 o2 F" d1 `% M      这个就没什么办法,只能硬着头皮调了。调整轮子的大小设置,实际上就是调马达转速,没有什么更有效的解决办法
8 P2 @/ G3 ?" F+ a4 ^) K& R/ O  起始位置车子正方向和直线间的夹角4 o9 H5 p9 O: ~5 d& \
      一个非常重要的因素,可谓差之毫厘谬以千里。所以尽可能减小两者的方向差。顺带一提,开环控制的小车,如果最终结果差距在一厘米只内,就已经没有什么可比性了。一厘米之内运气成分占比很大,因为0.01rad(0.5度以内)的夹角足以造成差距一厘米的偏差。这就是开环控制的特点
; T% ^5 v" F% {2 a% l
6 Y# m- ~  {/ h# X# U! R9 D5 Y0 f
! J' q5 }0 T+ k
然后上源代码:
  1. " J: P) o7 {1 L$ z2 L  d% V6 k
  2. importlejos.robotics.navigation.DifferentialPilot;
    1 [$ J6 ?. _5 m* H1 L# e! I
  3. import lejos.util.Delay;
    0 ~! w9 \% j+ {4 l. _

  4. % P, [6 }+ `' `
  5. /**
    . L& e' f6 ^  g9 M. c  ~
  6. *Robot that stops if the buttons are presses before it completes its travel.7 b( t1 }2 c, s2 c* p# u$ I) m- K
  7. */" o: h# t" Z2 s/ r+ q" H! D
  8. 5 J! u& w# Z# p% _8 [; m
  9. $ w, R. }. \8 H- Q; w0 t! x# i$ c
  10. public class Straight {
    4 w) @" T( l! Q2 c" D/ }: M
  11.   DifferentialPilotpilot;* G3 Y! c* O8 h% T# ]% D
  12.   doubleleftD = 4.3, rightD = 4.3;
    * Z6 m/ l$ O0 W' N: a9 ~

  13. $ w3 r& V; f5 ^
  14.   publicvoid adjust() {2 M8 @; U% k: R1 F: N7 o
  15.            //wait for release0 S  e9 a) Y; z+ V4 Q: ~/ x
  16.            while(Button.readButtons() > 0)
    # z* l! u6 t0 B0 K3 a
  17.                    ;
    5 `: ?: S& ^0 a8 A0 _+ D' l8 ^9 F
  18.            while(Button.readButtons() == 0) {* r& z# L% @5 e2 g' [
  19.                    //input size by adjusting the wheels2 F1 j; m) {8 @; L5 f
  20.                    rightD= (double) (Motor.A.getTachoCount()) / 2160 + 4.3;9 [; x( j) `, D9 [- V# V' b
  21.                    leftD= (double) (Motor.B.getTachoCount()) / 2160 + 4.3148;// 调试所得值4 n: U4 Y: [8 ^; `% q% ?
  22. ) P( }) V/ A$ Z
  23.                    //display the size input
    7 J8 k  ^2 ]) w" E* D
  24.                    LCD.drawString("L:"+ String.valueOf(leftD), 0, 0);
    8 `8 ~, U; d# U$ u! `' A
  25.                    LCD.drawString("R:"+ String.valueOf(rightD), 0, 1);
    . o% T1 d8 t; P% g
  26.                    Delay.msDelay(100);  h6 E* D, w  w* @- j5 ^
  27.                    LCD.clear();+ G1 C( J0 a4 G  e$ a( u
  28.            }* M) G" s0 V/ ~/ I/ O3 U. Y  t
  29. ' M9 m  @" ]' X! V& Q9 }& F+ }- A7 o
  30.   }
    ( i1 R6 y% d' N1 d# l

  31. " S0 {( c; `, `* a" y0 q& o5 q; g
  32.   publicvoid go() {
    , p& Z, E) ^4 q
  33.            //准备起步
    : @' T' W; t5 K4 p
  34.            //wait for release
    5 W3 R' c5 g. ]& S; c
  35.            while(Button.readButtons() > 0)
    ( n! V. m& y/ E
  36.                    ;
    ) U2 z" }! P) I
  37.            System.out.println("pressto go");% [' M  t( `& V4 q9 K

  38. 3 b0 A9 i( S) o% H% M' t( _0 [) l
  39.            Button.waitForAnyPress();; l3 P& Y  c: h$ N: a
  40.            LCD.clear();
    ' A9 l+ a, \0 I0 N, Q
  41. + M2 u* Y5 m' m. z  F" b$ L+ h
  42.            //初始化
    1 w( U5 F6 }5 K' ^6 ]5 {
  43.            pilot= new DifferentialPilot(rightD, leftD, 13.5, Motor.A, Motor.B, true);( ~) _8 U4 c$ v0 J5 `, \  ?* Z
  44.            pilot.reset();
    ; Z9 \3 L6 H  J: V
  45. 8 @8 {2 U; b0 Y( O3 G
  46.            Delay.msDelay(3000);
    0 ~6 s/ l4 M0 b( O, x6 E8 N/ o1 J
  47. 1 d, |: O) e2 ]: T
  48.            doublespeed = 10;
    . i: V, R# m) d1 O  F, @. x% Y
  49.            doubledistance = 0;$ f+ @2 Z) o0 Y4 b( R  ]

  50. 8 b/ A: u6 a' j" g: P$ r
  51.            //起步加速2 d* {& A! O" X
  52.            pilot.travel(300,true);' H0 Z& `+ Z. w- M- K. V

  53. : i5 F6 O( H- X3 [" V' c& r
  54.            while(distance < 20) {* ?$ Z7 ~6 u/ Z- s( ?
  55.                    distance= pilot.getMovement().getDistanceTraveled();
    " ^- f, m% Z" t9 w4 b" }
  56.                    speed= distance * 5 + 10;
    ' {& t- J. _. B! o( _
  57.                    pilot.setRotateSpeed(speed);
    5 ?# _# _) o0 J
  58.                    Delay.msDelay(100);
    . m' x$ i( f# Q8 {( }, V* E6 v
  59.            }
    8 G. q2 R& y4 c3 l+ w0 f
  60.            for(int i = 0; i < 10; i++) {
    9 C7 V; t& @. T  S  E6 [
  61.                    speed+= 5;
    7 U4 Q. K9 L9 K
  62.                    pilot.setRotateSpeed(speed);. I) U& M6 l" a6 Z0 A% O
  63.                    Delay.msDelay(200);
    ' z; K3 N; W. D& l3 t* j8 Q! B6 P2 v
  64.            }# m3 E1 O' L9 e, [) z: e) s2 S
  65. : j, V+ p' M9 o
  66.            //TODO 减速
    4 P6 y  s! q8 t6 K( H8 j# d+ D1 H
  67. 6 K( K$ a: R+ o! m
  68.            //停止机能' ?! ^& [; ?9 X, z9 m0 s/ C
  69.            while(pilot.isMoving()) {, y- G" c0 n; m; G
  70.                    if(Button.readButtons() > 0)
    7 F  q" B. G# Q# M  Y8 H% ?
  71.                            pilot.stop();. ~  ~, R7 ]( a$ R0 H! A# A# u
  72.            }
    ! ?: f1 O% c5 j$ u
  73. 8 Z( p; K/ J5 @2 E+ L
  74.            System.out.println("" + pilot.getMovement().getDistanceTraveled());
    & p% E# O, D6 E6 A0 Y: M% ]* E
  75.            System.out.println(-Motor.A.getTachoCount());6 f% j: m4 U; {
  76.            System.out.println(-Motor.B.getTachoCount());
    1 [( c3 Q. w$ a
  77.            Button.waitForAnyPress();
    1 z$ J" s6 H# Q
  78.   }: Z" l; A: t7 T0 ~4 a
  79. 3 [6 x) }6 \" d$ j2 q9 J& F* d
  80.   publicstatic void main(String[] args) {
    2 D3 f8 H/ k* z! S$ U% Z
  81.            Straighttraveler = new Straight();
    6 U# g5 v# z0 Y; a" y/ l. ?

  82. + _# d8 W, Q- Y
  83.            traveler.adjust();4 P) I; z# P) ^, j1 q
  84.            traveler.go();' T6 P) Y( ^2 R
  85.   }3 d7 C. P$ H) B" {) x& ~# M
  86. }
复制代码
" m: O6 T) ?+ ~& J# ]" P
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 编辑 3 L' l- |9 ~5 {0 U8 o
1 D0 S: e$ A& E( i# H
这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨,用代码程序的机器人都能很好的实现复杂功能
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

 楼主| 发表于 2017-7-26 10:08:44 | 显示全部楼层
clx 发表于 2017-7-26 07:22
  ~/ O/ Z' W4 m4 V* @+ w1 N这一行行代码,C?,暂还不懂,反正看到写代码的都敬仰,这种程序是不是比G(乐高是不是叫G语言)的严谨, ...
/ V# r! @3 u8 L
我用的是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-7-2 06:21 , Processed in 0.241420 second(s), 21 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

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