|
@@ -10,6 +10,7 @@
|
|
|
#include <geometry_msgs/Twist.h>
|
|
|
#include <tf/transform_listener.h>
|
|
|
#include <nav_msgs/Odometry.h>
|
|
|
+#include <std_msgs/Float32.h>
|
|
|
|
|
|
|
|
|
#define TURN_LEFT 0
|
|
@@ -29,9 +30,9 @@ float right_dist;
|
|
|
std::string odomFrame;
|
|
|
std::string baseFrame;
|
|
|
|
|
|
-float linear_x_speed = 0.18;
|
|
|
-float linear_y_speed = 0.16;
|
|
|
-float angular_speed = 0.4;
|
|
|
+float linear_x_speed = 0.17;
|
|
|
+float linear_y_speed = 0.15;
|
|
|
+float angular_speed = 0.5;
|
|
|
|
|
|
/*********************************************************
|
|
|
* Descripition: 发布控制移动的消息,这里对于平面移动的
|
|
@@ -56,11 +57,11 @@ void publishTwistCmd(float linear_x, float linear_y, float angular_z)
|
|
|
* Description:控制小车移动在过道中间,比较左右两边的距离后
|
|
|
* 然后进行水平左右移动.
|
|
|
**********************************************************/
|
|
|
-void horizontallyMoveMiddle(float left_dis,float right_dis,float tolerance)
|
|
|
+void horizMoveMiddle(float left,float right,float tolerance)
|
|
|
{
|
|
|
- float diff = left_dis - right_dis;
|
|
|
- //ROS_INFO("left right diff:%f", diff);
|
|
|
- if((fabs(diff) > tolerance)&&(left_dis != 0.300000)&&(right_dis != 0.300000))
|
|
|
+ float diff = left - right;
|
|
|
+ ROS_INFO("diff:%f,left:%f,right:%f",diff,left,right);
|
|
|
+ if((fabs(diff) > tolerance)&&(left!=(float)0.3)&&(right!=(float)0.3))
|
|
|
{
|
|
|
if(diff < 0) //move right
|
|
|
{
|
|
@@ -80,6 +81,45 @@ void horizontallyMoveMiddle(float left_dis,float right_dis,float tolerance)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/****************************************************
|
|
|
+ * Description:控制小车前进移动0.5m
|
|
|
+ ***************************************************/
|
|
|
+void goForward()
|
|
|
+{
|
|
|
+ tf::TransformListener tf_Listener;
|
|
|
+ tf::StampedTransform tf_Transform;
|
|
|
+ float dist = 0.0;
|
|
|
+ float check_dist = 0.5;
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ tf_Listener.waitForTransform(odomFrame, baseFrame, ros::Time(0), ros::Duration(5.0));
|
|
|
+ }
|
|
|
+ catch(tf::TransformException &ex)
|
|
|
+ {
|
|
|
+ ROS_ERROR("tf_Listener.waitForTransform timeout error !");
|
|
|
+ ROS_ERROR("%s",ex.what());
|
|
|
+ ros::shutdown();
|
|
|
+ }
|
|
|
+
|
|
|
+ tf_Listener.lookupTransform(odomFrame, baseFrame, ros::Time(0), tf_Transform);
|
|
|
+ float x_start = tf_Transform.getOrigin().x();
|
|
|
+ float y_start = tf_Transform.getOrigin().y();
|
|
|
+ while((dist < check_dist) && (ros::ok()))
|
|
|
+ {
|
|
|
+ ROS_INFO("Go forward ...");
|
|
|
+ publishTwistCmd(linear_x_speed, 0, 0);
|
|
|
+ ros::Duration(0.10).sleep(); //100 ms
|
|
|
+ tf_Listener.lookupTransform(odomFrame, baseFrame, ros::Time(0),tf_Transform);
|
|
|
+ float x = tf_Transform.getOrigin().x();
|
|
|
+ float y = tf_Transform.getOrigin().y();
|
|
|
+ dist = sqrt(pow((x - x_start), 2) + pow((y - y_start), 2));
|
|
|
+ }
|
|
|
+ publishTwistCmd(0, 0, 0); //stop move
|
|
|
+ ROS_INFO("Go forward finish !!!");
|
|
|
+ ros::Duration(0.3).sleep(); //300 ms
|
|
|
+}
|
|
|
+
|
|
|
/**************************************************
|
|
|
* Description:控制小车左右转90度,或者掉头180度.
|
|
|
*************************************************/
|
|
@@ -133,7 +173,7 @@ int controlTurn(int flag)
|
|
|
{
|
|
|
ROS_INFO("Turning ...");
|
|
|
publishTwistCmd(0, 0, angular); //原地转弯,不需要linear_x,y的控制
|
|
|
- ros::Duration(0.04).sleep(); //40 ms
|
|
|
+ ros::Duration(0.10).sleep(); //100 ms
|
|
|
|
|
|
try
|
|
|
{
|
|
@@ -151,6 +191,7 @@ int controlTurn(int flag)
|
|
|
last_angle = rotation;
|
|
|
//ROS_INFO("turn_angle:%f",turn_angle);
|
|
|
}
|
|
|
+ publishTwistCmd(0, 0, 0); //原地转弯,不需要linear_x,y的控制
|
|
|
ROS_INFO("Turning finish !!!");
|
|
|
ros::Duration(0.3).sleep(); //300 ms
|
|
|
|
|
@@ -158,53 +199,72 @@ int controlTurn(int flag)
|
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
|
- * Description:检查三个传感器数据,然后控制小车移动.
|
|
|
+ * Description:检查三个传感器数据,然后控制小车移动.这里需要防止小车在原地
|
|
|
+ * 进行连续两次旋转,在每次转弯后必须有个直行.
|
|
|
**************************************************************************/
|
|
|
void checkInfraredDist(float infrared_f,float infrared_l,float infrared_r,
|
|
|
float tolerance)
|
|
|
{
|
|
|
- if(infrared_f < warn_dist*2.0) //前边距离小于警告值
|
|
|
+ static int flag = 0;
|
|
|
+ static int cnt = 0;
|
|
|
+
|
|
|
+ if((infrared_l == (float)0.3)&&(!flag))
|
|
|
{
|
|
|
- if(infrared_l > infrared_r)
|
|
|
+ cnt++;
|
|
|
+ ROS_WARN("Ready turn Left !");
|
|
|
+ if(cnt >= 7)
|
|
|
{
|
|
|
ROS_WARN("turn Left !");
|
|
|
controlTurn(TURN_LEFT);
|
|
|
+ flag = 1;
|
|
|
+ cnt = 0;
|
|
|
}
|
|
|
- else if(infrared_l < infrared_r)
|
|
|
+ if(infrared_f > tolerance*4.0)
|
|
|
{
|
|
|
- ROS_WARN("turn Right !");
|
|
|
- controlTurn(TURN_RIGHT);
|
|
|
+ ROS_WARN("continue go forward !");
|
|
|
+ //始终控制小车保持在过道的中间位置
|
|
|
+ horizMoveMiddle(infrared_l, infrared_r, tolerance);
|
|
|
+ publishTwistCmd(linear_x_speed, 0, 0); //go forward
|
|
|
}
|
|
|
-#if 0
|
|
|
- if(fabs(infrared_l - infrared_r) > tolerance)
|
|
|
+ }
|
|
|
+ else if(infrared_f > tolerance*4.0)
|
|
|
+ {
|
|
|
+ //始终控制小车保持在过道的中间位置
|
|
|
+ horizMoveMiddle(infrared_l, infrared_r, tolerance);
|
|
|
+ publishTwistCmd(linear_x_speed, 0, 0); //go forward
|
|
|
+ flag = 0;
|
|
|
+ }
|
|
|
+ else if((infrared_r == (float)0.3)&&(!flag))
|
|
|
+ {
|
|
|
+ cnt++;
|
|
|
+ ROS_WARN("Ready turn Right !");
|
|
|
+ if(cnt >= 7)
|
|
|
{
|
|
|
- if(infrared_l > infrared_r)
|
|
|
- {
|
|
|
- ROS_WARN("turn Left !");
|
|
|
- controlTurn(TURN_LEFT);
|
|
|
- }
|
|
|
- else if(infrared_l < infrared_r)
|
|
|
- {
|
|
|
- ROS_WARN("turn Right !");
|
|
|
- controlTurn(TURN_RIGHT);
|
|
|
- }
|
|
|
+ ROS_WARN("turn Right !");
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ flag = 1;
|
|
|
+ cnt = 0;
|
|
|
}
|
|
|
- else
|
|
|
+ if(infrared_f > tolerance*4.0)
|
|
|
{
|
|
|
- ROS_WARN("turn Back !");
|
|
|
- controlTurn(TURN_BACK);
|
|
|
+ ROS_WARN("continue go forward !");
|
|
|
+ //始终控制小车保持在过道的中间位置
|
|
|
+ horizMoveMiddle(infrared_l, infrared_r, tolerance);
|
|
|
+ publishTwistCmd(linear_x_speed, 0, 0); //go forward
|
|
|
}
|
|
|
-#endif
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- //始终控制小车保持在过道的中间位置
|
|
|
- horizontallyMoveMiddle(infrared_l, infrared_r, tolerance);
|
|
|
- ROS_INFO("Go forward, linear_x:%f", linear_x_speed);
|
|
|
- publishTwistCmd(linear_x_speed, 0, 0);
|
|
|
+ ROS_WARN("turn Back !");
|
|
|
+ controlTurn(TURN_BACK);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void yaw_callback(const std_msgs::Float32::ConstPtr& msg)
|
|
|
+{
|
|
|
+ ROS_INFO("Yaw data:%f", msg->data);
|
|
|
+}
|
|
|
+
|
|
|
/*****************************************************************************
|
|
|
* Description: 订阅红外测距传感器话题后的回调函数,根据三个传感器数据进行走
|
|
|
* 迷宫.
|
|
@@ -225,6 +285,7 @@ int main(int argc, char **argv)
|
|
|
{
|
|
|
std::string infrared_topic;
|
|
|
std::string cmd_topic;
|
|
|
+ std::string yaw_topic;
|
|
|
|
|
|
ros::init(argc, argv, "infrared_maze_node");
|
|
|
ros::NodeHandle handle;
|
|
@@ -238,10 +299,21 @@ int main(int argc, char **argv)
|
|
|
ros::param::get("~tolerance_dist", tolerance_dist);
|
|
|
ros::param::get("~odom_frame", odomFrame);
|
|
|
ros::param::get("~base_frame", baseFrame);
|
|
|
+ ros::param::get("~yaw_topic", yaw_topic);
|
|
|
|
|
|
ros::Subscriber sub_infrared = handle.subscribe(infrared_topic, 1, infrared_callback);
|
|
|
+ ros::Subscriber sub_yaw = handle.subscribe(yaw_topic, 1, yaw_callback);
|
|
|
twist_pub = handle.advertise<geometry_msgs::Twist>(cmd_topic, 1);
|
|
|
-
|
|
|
+#if 0
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ ros::Duration(3).sleep(); //300 ms
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ ros::Duration(3).sleep(); //300 ms
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ ros::Duration(3).sleep(); //300 ms
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ ros::Duration(3).sleep(); //300 ms
|
|
|
+#endif
|
|
|
ros::spin();
|
|
|
return 0;
|
|
|
}
|