找回密码
 注册
关于网站域名变更的通知
查看: 692|回复: 1
打印 上一主题 下一主题

TFmini与舵机结合的机器人小车避障应用方案

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-7-16 15:16 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 jacky401 于 2019-7-16 18:15 编辑 3 n' Z9 ^- x$ W# H4 o/ t
/ d. H$ n( K2 O' F3 ]/ k
1.试验设备及接线
. G8 @# K1 N3 }- g, j. s; ]
1.1实验设备  
·        MiniQ 桌面机器人底盘
% U; Q/ x. U. N# t; t% u% n    & ]: v2 p8 ~( y$ o! D, T
- 底盘直径:122mm
+ L! L+ Y$ b8 g/ ~- 轮子直径:42mm ; y: o/ I9 t1 {$ R2 M3 w; \2 B7 P
- 底盘高度:15mm + Y4 d/ _2 z5 T8 v% K
- 兼容 Arduino 标准板及 Romeo 控制器固定孔 # B' G! s3 N) S
- 电机参数:
·           N20 电机电压:3-9V
·          无负载转速:13000rpm
·          50:1 减速箱
·          260rpm@6V
·          40mA@6V
·          360mA 堵转@6V
·          10 盎司英寸扭矩@6V
                                                      
·        Romeo 三合一 Arduino 兼容控制器
6 e* E% m  r. _+ \0 \% N. w
-
采用 Atmel Atmega328 单片机
$ Q! ]7 ~  W4 \* \. W- Arduino UNO bootloader % m1 z. |& `% I& n; g& s) ?' A
-
完全兼容 Aruduino UNO 的端口布局 8 q9 t! i; U4 i, F3 F/ @
-
集成 APC220 无线数传和 DF-BluetoothV3(SKU:TEL0026)蓝牙模块接口 ( M7 Y! K& O3 I3 U9 a! E4 k  h/ M& p7 u
-
支持 5 组 I2C 总线接口 ) G" V( R8 O& O  [4 r* B2 y& u2 P
-
支持两路电机驱动,峰值电流 2A,4 个控制口使用跳线切换 6 D* q+ o$ I  c0 u
-
外部输入电压范围:6V~20V . {& |# z) h( Q# e  R2 P
-
更详细的参数介绍详见附录的网页地址。
1 \; S' S, P- v" C0 c
* U* _; l4 f: c( y
·        MiniQ 小车上层安装板

0 |( z" ^( y4 ~8 I+ l& j+ q! e' z" _$ O. k0 a4 x
·        Benewake TFmini 标版
5 R3 C9 W3 L1 T4 O- h; d
TFmini
详细参数见 TFmini 使用说明。
& e; b- Y& {! y% f
1 \1 H8 @6 ]; ~9 a0 O
·        9g 舵机

4 n" N% ~* o* H  [$ a& D
1.2接线; a' O1 \# t( G* V1 c

. h; C; g# U  r  ~- {+ b
2.小车避障原理
) j8 R, x6 L# j. ?
小车启动后,小车开始向前运动。当雷达探测到前方阈值内有障碍物时,小车停止运动,开始左右扫描寻路。舵机搭载 TFmini 从 90°开始向 180°扫描,然后从 180°向 0°扫描。2 B. y! @/ W- u/ \$ F# Y% X& n
8 ^( z  E3 W4 |! @* c' {; W+ Q; X
当扫描方向无障碍物时,小车向此方向转向,舵机回正到 90°。若从左至右扫描一圈都没有可以行进的路线,则小车后退,舵机回正。 9 @3 u' i/ l: c- m7 u  r
逻辑流程图如下所示:
) e8 {& P( X6 w  ~
; Q: u& D4 p3 |2 B$ n2 C8 l- h
3.注意事项
·        当前避障原理模型只用来抛砖引玉,探索用 TFmini 避障的可行性,并不能大范围的适用于大规模的商业场景,如有需要,应以专业软件开发人员的代码为准。
·        搭载的外部电源过重时,会影响小车车轮的摩擦力,可能两个车轮的转速不一致,导致小车并不能按照轨迹行驶。
·        小车车轮在光滑地面有可能造成空转的现象,导致小车不能走直线。
·        如果单独对 TFmini 外部供电,则需将外部电源和控制板共地处理。
·        如果搭载更高复杂度的程序,要考虑芯片的能力,当前开发板在跑程序时已经发现会有卡顿的现象。
4.附录
; Z( b! ^- f6 b2 @$ y" b  |( Z" m
4.1代码' R  p; _3 }7 o0 T( {' ~
#include <Servo.h>
9 X: p+ n0 f1 B7 u5 s, |3 T' L2 K# ~, EServo myservo;) |& H# _- L% p8 A4 W' f. N! b
int pos=90; //
定义舵机角度" T* f+ N, V5 z4 B
bool flag=true;//
定义舵机转向
& w8 W) v& r- g  D& qfloat dist_f;//
定义foward 方向距离' D, \# w6 L- k0 \1 F
float dist_s;//
定义sideway 方向距离
  l7 J% p* Y- q8 H/ r3 K6 T/ uint E1=5; //
定义 M1 使能
0 w& T4 W1 M( V- P4 b" Z, @9 dint E2=6; //
定义 M2 使能
" `9 v4 L# C7 g" H, R+ vint M1=4; //
定义 M1 控制; X1 g0 B( n5 u% t6 D3 B
int M2=7; //
定义 M2 控制0 ]4 ~: j: B) S
int temp_distance =0;
/ k" R: V% U; i( n- O2 F, }/**$ H4 m2 w9 T. U% {4 V1 S/ u6 M" x; K
*
双轮停止
2 {, P* o8 g8 G/ h9 _& w" X*/
3 I5 O* Q6 L3 K6 evoid brake(void){
; P3 `% s/ I+ a7 o4 @( m3 ZdigitalWrite(E1,LOW); //
给 E1 低电平
# }; |0 W3 }* {$ @digitalWrite(E2,LOW); //
给 E2 低电平: @- k: P& f% }. c4 H7 y
}' v- I- }5 s+ I% s
/**
" x( K' K$ q9 b+ w. z$ h9 W*
双轮前进# e' I9 T3 r/ \; {. p9 P  c5 s
*/- ^0 q( p. C* q) ]; w: ^# z
void advance(char a, char b){
+ |6 I8 O' M: B3 Y( o! ^; NanalogWrite(E1,a);
. a/ g3 U) _1 t% pdigitalWrite(M1,LOW);
: d7 V/ X8 i5 J/ E( {: panalogWrite(E2,b);
& b( y; ?/ m5 i2 U9 n% G4 Z5 e. VdigitalWrite(M2,LOW);3 J) M) r- |6 h: z0 |% ~! B
}" W3 i4 ^$ X/ q+ U  K& n0 e
/**
  R7 `6 n0 X( Y8 S/ s+ A*
双轮后退0 _6 \5 l$ X  Z: r' L
*/" d) Y4 [5 W* H! x
void back(char a, char b){: |( X7 P4 ?5 Q
analogWrite(E1,a);
) o' ^2 J; w2 R4 T, b7 J2 EdigitalWrite(M1,HIGH);
' R$ s0 w$ {& P; eanalogWrite(E2,b);
. I) j) B) k$ v2 G3 S6 R8 XdigitalWrite(M2,HIGH);
) z3 Z' j2 i4 [6 C1 b% B2 g* }}9 Y2 m) o' W+ h* ?
/**: ~1 }: F) H% M' |
*
左转3 R. y( o2 Z) G2 d6 y/ y
*/
  V( m$ E; b+ F7 m5 @2 A2 Fvoid turn_L(char a, char b){
% E/ K/ J8 p! V7 U. RanalogWrite(E1,a);
4 I  N1 l+ j5 tdigitalWrite(M1,LOW);, Q, a) N) c7 Y' Z# j0 R
analogWrite(E2,b);
) ]( Z( b  ?# j# L# R* H* N# y- ddigitalWrite(M2,HIGH);
/ z* z0 g0 M7 M9 f! T}2 d3 G! b) {! J: |# w6 {; a
/**
" K* W6 P7 p' Z- v' V$ @% I*
右转
( c1 |7 Y$ K/ V3 M: Y* ^# v2 y*/1 V6 T7 L; y, B+ G9 q. s
void turn_R(char a, char b){  J% `+ g6 x' u* P7 W1 h
analogWrite(E1,a);: e3 D. }' ~  ?6 H" y& I
digitalWrite(M1,HIGH);* _: F. q* o$ s2 x$ h. ^
analogWrite(E2,b);8 Q, |% m5 o. Q4 p1 H. ~7 S& t$ [
digitalWrite(M2,LOW);8 {& G2 O: m; M) ~, _0 a4 z3 e
}6 V- o  N, O: _' p) [
/**7 ?( Z2 L& I! @8 d" h" h! T- }5 X
*
读取 TFmini 测量结果
( V2 U- c% K1 w: |" r% k9 V*/
8 o9 b. _+ E6 ^5 cvoid getTFminiData(int* distance, int* strength){( l9 Z# T* q; B3 F0 K* s
static char i = 0;
4 I# M4 Z. h8 b4 ?! J; rchar j = 0;
- C1 {9 h* ^9 h& d+ ^/ V* Y# \$ l& Oint checksum = 0;7 v4 _6 S9 i" }( x& j
static int rx[9];* A  N8 w7 n) \: q) h' b$ z. _. g
if(Serial.available()) {3 ?% ^0 j5 C( e6 ^% w) U) p0 z& U
rx = Serial.read();
' p* J& ^/ n* |& Wif(rx[0] != 0x59) {
& g5 ~, W0 z5 z/ ji = 0;7 Y* O) Q, J/ j  }$ E: H
} else if(i == 1 && rx[1] != 0x59) {& C- l' f0 [$ A$ E+ M' \/ ~! }
i = 0;
+ u7 Q4 k& x9 F" a& }  ?} else if(i == 8) {
6 u+ v& ]- c* [for(j = 0; j < 8; j++) {) U/ [/ y, |, D9 A+ _" b! f
checksum += rx[j];/ V8 D5 @2 f0 i+ r+ U9 l! Y
}9 H! _0 K% t3 T/ d
/*
; a& R4 o: e7 r" I- z9 c( R5 Hif(rx[8] == (checksum % 256)) {
& N! x2 t9 ^: s- s: C9 ?' \+ g*distance = rx[2] + rx[3] * 256;- U; L7 e; u# e8 x
*strength = rx[4] + rx[5] * 256;1 T: E# p+ i0 ~
}*/& T$ o9 O' m1 y
*distance = rx[2] + rx[3] * 256;: r- k( N4 v+ {
*strength = rx[4] + rx[5] * 256;, o" L1 A# S5 L9 Z
i = 0;
( e. q  v% {. @* j} else {
3 Y& X$ y2 V  ]* V/ Mi++;
8 }( i$ C/ {7 F) G; k& [: R. a}! C" Z$ a) q; e$ ?# |, @5 b
}. s2 N& ^) y2 h
}* v; p) }0 c3 O, f# H( `
void setup() {
3 D8 n$ d3 t* T: L+ K// put your setup code here, to run once:$ O7 L, U- S3 u+ X! v
Serial.begin(115200);' }+ d- S* g6 K2 p7 V
//
舵机的插口在 4' {* O( n4 T6 L: b: }
myservo.attach(4);
! l, E: J7 }/ o& Bbrake();; x" c& n+ M: u: @  O# ]7 L' f3 S6 A
/*
% ?9 ]2 z. Q& D9 y! T* 将雷达指向前方
# T0 n$ `- z$ O- y/ z5 i. ]; \% ?0 @*/
1 h& E  ^! {, [# H  nmyservo.write(pos);+ Q0 X; u; `+ \7 u9 g
/*1 J/ U8 {) m- R- u6 U( x/ }
* 设置轮胎电机输出口; x7 W% D( v) X  ~/ |6 Q' ~
*/, W( c% B) S) a
pinMode(4,OUTPUT);, X$ _- D7 M0 o/ S4 t/ o5 j
pinMode(5,OUTPUT);
$ S; a; x6 C% N' vpinMode(6,OUTPUT);
3 U/ F* \5 D* I; f2 d& @pinMode(7,OUTPUT);& c. i" |  f" k  D
delay(10);
3 x. e+ _1 j2 h}0 A8 T  B; V. D0 d
void loop() {) Z1 h/ X" R# \, d. Y# J
/*, q3 g, r5 S4 f
* 读数一次
' p" X9 A4 n3 Z3 n*/! L% R( M( X& I4 h/ A3 ~$ h
int distance = 0;8 A8 Z6 `: s. H  B7 s
int strength = 0;
1 H& S( b; B) a% pgetTFminiData(&distance, &strength);: X+ _3 E! b: F( B0 L: l* h" D
while(!distance) {
. |# ?! q6 A6 J$ B) kgetTFminiData(&distance, &strength);
- p+ G+ h! R9 H  H+ p; O; l  |Serial.print("Distance: ");
- D( t  f5 d) a' s% x0 n6 h, fSerial.print(distance);4 x: Y  X+ h5 [7 ^. w) b* v/ b
Serial.print("cm ");0 R/ Q* H8 _5 P! E) M
Serial.print("strength: ");
$ m8 j# a' s# {: L2 u6 E0 n9 [Serial.println(strength);8 k' A5 N; ]* d6 S; o( u8 b
}
$ K: \% Z9 J- |! q: e6 Y/*
- \* Y2 j5 n  e. P) C6 B: \* 设置 30CM 阈值
7 s- n0 Y. e3 G( ?6 _0 G" K*/0 u: i" D# {9 z0 j! y8 W( i  e+ A# K! B
if(distance <= 30 && distance > 0){
; k1 i/ ]; s9 z. M$ R; K/ w8 J: Ztemp_distance = distance;
  b4 s4 g& R$ e8 {}* E1 S( e. n% j: |& K6 h
delay(10);
8 \( Y8 d5 |  S1 E% S/*9 q; x5 k4 a; F# w4 L$ u
* 判断读数距离
$ X8 p  Y5 G. k0 @5 E0 u0 u6 f2 q* 如果度数距离小于阈值,则停车,开始向左向右扫描,直到扫描出有空隙可以走,然后车轮转弯,然后扫描器回正
  H" }' a% C9 g# [. N* 如果读数距离大于阈值,则开车
$ {4 o6 {; X: J. g3 S' P9 n*/0 f! d4 b, N+ q( i6 z4 a
if(temp_distance <= 30 && temp_distance >= 0){
0 }* s1 l4 K; k( y$ r- d1 Q! H. Xbrake();
$ d2 B7 a# h& a/ @* Y, k& A& R, o/*
. }+ F" j: K$ L$ s* v- T7 ~; t* 判断当前舵机应该向左还是向右转. \- ~! C. T: @
*/
. o0 H  a* A$ N- Oif(flag){
/ n/ h2 q- f+ h4 [$ P7 ^- Kif(pos<170){$ I. V8 B; w6 z
pos=pos+45;: T: n$ @# g! ]. F- A! O& e2 Y* j
}else{
- N% m2 B$ U' j3 A1 d& sflag = false;& }* b# H, l3 q' G6 c
}% l8 I! f4 r4 U7 ?( B& s2 z, ^% ]
/** Q9 r# [$ M! J0 m3 c% z' |
* 如果探测距离大于阈值,则舵机回正,小车转向
- C* }' p5 r2 c0 x8 J% y8 G) e*/
( o. `; }! o9 L2 u1 z5 `/ mif(distance > 32){5 z  I% Y# q4 w% s7 R% U
pos = 90;7 x' w& V8 P7 R/ N$ P; h0 @! G
myservo.write(pos);
! M# Z; Z% P7 Y  E% Zdelay(1200);
1 G8 u0 u0 Q$ G# G4 ^3 r9 C//判断小车回正方向
* o& V) f+ e# {if(pos >= 90){
% {0 h7 ~2 i; }1 @" q+ Y  ?5 c; l% bturn_L(35,35);
$ {$ |$ s5 ^: \0 U3 ]0 o/ j}else{9 z% Z' h7 O6 S( i1 X
turn_R(35,35);
/ i; W/ \+ K( ~8 D}
, I/ y' ]4 m- Cdelay(250);
' c8 I& n: Y1 F5 \temp_distance = distance;
; ~3 p* D* U  u! H}
0 d+ X2 f9 _. `8 j. I7 j/*! _+ S' T  U2 M
* 如果探测距离小于阈值,则继续扫描
, o3 p1 T2 k9 d*/
4 X; y; s, \" W. B0 |' p: ~2 H& uelse{
' f: H4 ?7 ~& r: k' Z+ ?myservo.write(pos);
" i; R/ c* D8 Tdelay(1200);
4 w2 n) m. t5 ]" c9 s3 A}
8 G7 d6 a  H. Z: p1 K+ m. i}else{
) G8 i/ c! w8 \% {7 Hif(pos>10){
) C' _! F8 r6 Q8 F& opos=pos-45;
0 l/ @6 s& B9 m" E}else{
: U2 Q& v% n3 h, s9 G* l. Pflag=true;
* o4 {! q' i9 I5 e& S}
  j7 a: f* ?' Y/ K& [. l! o' T# {' N/*/ |" X1 d# \3 o5 @7 @: \6 S; e
* 如果探测距离大于阈值,则舵机回正,小车转向
" E" }; i+ j1 s& h+ C*/0 ]% d% a5 Z. E8 g7 S/ B4 V
if(distance > 32){
; w$ Y) B6 a6 i, ^( Y- P4 g3 U3 qpos = 90;
/ x6 s* i$ `' B: rmyservo.write(pos);
8 V1 n3 x0 o  K4 h* n% X! Ydelay(1200);. _6 z: y+ f9 W/ t, T& _4 f5 ?
//判断小车回正方向
/ x  R  \: F; ?if(pos >= 90){: }; B2 X. v% w3 a
turn_L(35,35);
9 ~' \0 M, \) d" Z8 X* t}else{+ K' K' X, o' L9 s  V
turn_R(35,35);
4 V. {: D3 |7 [  U" w' X8 a}
( [* g: O) e+ L. l- v' ?2 Tdelay(250);; i( }7 `4 o9 t0 k" v/ ?
temp_distance = distance;# |2 N. y# @. d8 l, l
}2 W/ _# w, Q5 r- i
/*
& W" L  H& J1 _% s* 如果探测距离小于阈值,则继续扫描
0 q3 @/ e. T* D*/
9 h  G# F% j( `+ ?* D* `else{
% X' H9 \; ]8 |* R& c. D( `4 F: qmyservo.write(pos);
: G2 J: p$ w# p9 ^  C/ J. ?delay(1200);
) n+ v( c5 H" T7 A; k. B  Z7 c/ n}
& p) E6 W2 X* M8 p1 z, e6 K* V}- T% a* I; @6 _0 Z1 z, a3 a6 F# d" w% d
}5 t6 I: R, L( r1 t) [7 C4 ?
/*
/ N/ m/ ~% a  _2 @5 _9 E: C* 如果前方没有障碍物,直行
, s& D* Z' `) ~*/
1 A6 Z) b  ^1 n0 Q  Z  welse if(distance > 32 && distance < 1200){5 w' a( ^/ ~  B6 r
advance(35,35);* b: x: A# s5 S# H+ K8 [7 O: @9 V
}* p( c  B+ V% a
/*1 ^% W* S" V, @
* 如果雷达挂了,小车停止
4 N; B! V: j! X' u*/1 Q* q* w& d' _" r
else if(distance == -3){5 V* F3 ~  z  s* p! V
brake();* d- F8 X1 w* n$ Y7 M
}: e% ?9 ^$ c: ?5 v- g) C
}

* Y$ S) N% a- l- m
0 f; e% C' N! @

该用户从未签到

2#
发表于 2019-7-16 21:15 | 只看该作者
欢迎分享技术,拒绝广告内容!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-2 18:21 , Processed in 0.187500 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

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