|
@@ -1,15 +1,17 @@
|
|
|
/**************************************************************
|
|
|
- *Copyright(C): ROS小课堂 www.corvin.cn
|
|
|
- *FileName: getdata.cpp
|
|
|
- *Author: jally
|
|
|
- *Date: 20200325
|
|
|
- *Description:三轮小车进行红外避障
|
|
|
- *
|
|
|
+ Copyright(C): 2016-2020 ROS小课堂 www.corvin.cn
|
|
|
+ Description:三轮小车进行红外避障走迷宫.
|
|
|
+ Author: jally, corvin
|
|
|
+ History:
|
|
|
+ 20200404:增加可以直接转90度,掉头的功能 by corvin.
|
|
|
**************************************************************/
|
|
|
-#include "ros/ros.h"
|
|
|
+#include <ros/ros.h>
|
|
|
#include "ros_arduino_msgs/InfraredSensors.h"
|
|
|
-#include "geometry_msgs/Twist.h"
|
|
|
-
|
|
|
+#include <geometry_msgs/Twist.h>
|
|
|
+#include <tf/transform_listener.h>
|
|
|
+#include <nav_msgs/Odometry.h>
|
|
|
+
|
|
|
+
|
|
|
#define setbit(x, y) x|=(1<<y)
|
|
|
#define clrbit(x, y) x&=~(1<<y)
|
|
|
|
|
@@ -24,11 +26,15 @@
|
|
|
#define STATUS_F 0x03 // x v v
|
|
|
#define STATUS_G 0x05 // v x v
|
|
|
|
|
|
+#define TURN_LEFT 0
|
|
|
+#define TURN_RIGHT 1
|
|
|
+#define TURN_BACK 2
|
|
|
+
|
|
|
//global variable
|
|
|
geometry_msgs::Twist twist_cmd;
|
|
|
ros::Publisher twist_pub;
|
|
|
|
|
|
-const double warn_dist = 0.25; //warn check distance
|
|
|
+const double warn_dist = 0.15; //warn check distance
|
|
|
|
|
|
double default_period_hz = 10; //hz
|
|
|
double default_linear_x = 0.15; // (m/s)
|
|
@@ -38,15 +44,12 @@ double front_dist;
|
|
|
double left_dist;
|
|
|
double right_dist;
|
|
|
|
|
|
-void infrared_callback(const ros_arduino_msgs::InfraredSensors::ConstPtr& msg)
|
|
|
-{
|
|
|
- ROS_INFO("front distance:[%f]", msg->front_dist);
|
|
|
- front_dist = msg->front_dist;
|
|
|
- ROS_INFO("left distance:[%f]", msg->left_dist);
|
|
|
- left_dist = msg->left_dist;
|
|
|
- ROS_INFO("right distance:[%f]", msg->right_dist);
|
|
|
- right_dist = msg->right_dist;
|
|
|
-}
|
|
|
+std::string odomFrame;
|
|
|
+std::string baseFrame;
|
|
|
+
|
|
|
+float linear_speed;
|
|
|
+float angular_speed;
|
|
|
+
|
|
|
|
|
|
void publishTwistCmd(double linear_x, double angular_z)
|
|
|
{
|
|
@@ -61,6 +64,61 @@ void publishTwistCmd(double linear_x, double angular_z)
|
|
|
twist_pub.publish(twist_cmd);
|
|
|
}
|
|
|
|
|
|
+void controlTurn(int flag)
|
|
|
+{
|
|
|
+ tf::TransformListener tf_Listener;
|
|
|
+ tf::StampedTransform tf_Transform;
|
|
|
+ int angular = 0;
|
|
|
+ int check_angle = 0;
|
|
|
+
|
|
|
+ switch(flag)
|
|
|
+ {
|
|
|
+ case TURN_LEFT:
|
|
|
+ angular = angular_speed;
|
|
|
+ check_angle = M_PI/2;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TURN_RIGHT:
|
|
|
+ angular = -angular_speed;
|
|
|
+ check_angle = M_PI/2;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TURN_BACK:
|
|
|
+ check_angle = M_PI;
|
|
|
+ angular = angular_speed;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ tf_Listener.waitForTransform(odomFrame, baseFrame, ros::Time(), ros::Duration(2.0));
|
|
|
+ }
|
|
|
+ catch(tf::TransformException &ex)
|
|
|
+ {
|
|
|
+ ROS_ERROR("waitForTransform timeout error !");
|
|
|
+ ros::shutdown();
|
|
|
+ }
|
|
|
+
|
|
|
+ double last_angle = fabs(tf::getYaw(tf_Transform.getRotation()));
|
|
|
+ double turn_angle = 0;
|
|
|
+ while((fabs(turn_angle) < check_angle)&&(ros::ok()))
|
|
|
+ {
|
|
|
+ ROS_INFO("Turning ...");
|
|
|
+ publishTwistCmd(0, angular);
|
|
|
+ ros::Duration(0.05).sleep(); //50 ms
|
|
|
+
|
|
|
+ tf_Listener.lookupTransform(odomFrame, baseFrame, ros::Time(0), tf_Transform);
|
|
|
+ double rotation = fabs(tf::getYaw(tf_Transform.getRotation()));
|
|
|
+ double delta_angle = fabs(rotation - last_angle);
|
|
|
+
|
|
|
+ turn_angle += delta_angle;
|
|
|
+ last_angle = rotation;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void checkInfraredDist(double infrared_f, double infrared_l, double infrared_r)
|
|
|
{
|
|
|
unsigned char flag = 0;
|
|
@@ -97,7 +155,8 @@ void checkInfraredDist(double infrared_f, double infrared_l, double infrared_r)
|
|
|
{
|
|
|
case STATUS_A: //turn right 0x04
|
|
|
ROS_WARN("left warn,turn right");
|
|
|
- publishTwistCmd(0, -default_yaw_rate);
|
|
|
+ //publishTwistCmd(0, -default_yaw_rate);
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
break;
|
|
|
|
|
|
case STATUS_B: // 0x02
|
|
@@ -105,65 +164,85 @@ void checkInfraredDist(double infrared_f, double infrared_l, double infrared_r)
|
|
|
if(infrared_l > infrared_r)
|
|
|
{
|
|
|
ROS_WARN("turn left");
|
|
|
- publishTwistCmd(0, 2*default_yaw_rate);
|
|
|
+ controlTurn(TURN_LEFT);
|
|
|
+ //publishTwistCmd(0, 2*default_yaw_rate);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ROS_WARN("turn right");
|
|
|
- publishTwistCmd(0, -default_yaw_rate*2);
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ //publishTwistCmd(0, -default_yaw_rate*2);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case STATUS_C: //turn left
|
|
|
ROS_WARN("left ok, front ok, right warn, turn left");
|
|
|
- publishTwistCmd(0, default_yaw_rate);
|
|
|
+ //publishTwistCmd(0, default_yaw_rate);
|
|
|
+ controlTurn(TURN_LEFT);
|
|
|
break;
|
|
|
|
|
|
case STATUS_D:
|
|
|
ROS_WARN("left,front,right all warn, turn back");
|
|
|
- publishTwistCmd(0, 10*default_yaw_rate);
|
|
|
+ controlTurn(TURN_BACK);
|
|
|
+ //publishTwistCmd(0, 10*default_yaw_rate);
|
|
|
break;
|
|
|
|
|
|
case STATUS_E:
|
|
|
ROS_WARN("left warn, front warn, right ok, turn right");
|
|
|
- publishTwistCmd(0, (-default_yaw_rate*2));
|
|
|
+ controlTurn(TURN_RIGHT);
|
|
|
+ //publishTwistCmd(0, (-default_yaw_rate*2));
|
|
|
break;
|
|
|
|
|
|
case STATUS_F:
|
|
|
ROS_WARN("left ok, front warn, right warn, turn left");
|
|
|
- publishTwistCmd(0, (default_yaw_rate*2));
|
|
|
+ controlTurn(TURN_LEFT);
|
|
|
+ //publishTwistCmd(0, (default_yaw_rate*2));
|
|
|
break;
|
|
|
|
|
|
case STATUS_G:
|
|
|
ROS_WARN("left and right warn, front ok, speed up");
|
|
|
- publishTwistCmd(2*default_linear_x, 0);
|
|
|
+ publishTwistCmd(default_linear_x, 0);
|
|
|
+ //publishTwistCmd(2*default_linear_x, 0);
|
|
|
break;
|
|
|
|
|
|
default: //go forward straight line
|
|
|
publishTwistCmd(default_linear_x, 0);
|
|
|
break;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+void infrared_callback(const ros_arduino_msgs::InfraredSensors::ConstPtr& msg)
|
|
|
+{
|
|
|
+ ROS_INFO("front distance:[%f]", msg->front_dist);
|
|
|
+ front_dist = msg->front_dist;
|
|
|
+
|
|
|
+ ROS_INFO("left distance:[%f]", msg->left_dist);
|
|
|
+ left_dist = msg->left_dist;
|
|
|
+
|
|
|
+ ROS_INFO("right distance:[%f]", msg->right_dist);
|
|
|
+ right_dist = msg->right_dist;
|
|
|
+
|
|
|
+ checkInfraredDist(front_dist, left_dist, right_dist);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
int main(int argc, char **argv)
|
|
|
{
|
|
|
+ std::string infrared_topic;
|
|
|
+ std::string cmd_topic;
|
|
|
+
|
|
|
ros::init(argc, argv, "infrared_maze_node");
|
|
|
ros::NodeHandle handle;
|
|
|
- ros::Rate loop_rate = default_period_hz;
|
|
|
-
|
|
|
- ros::Subscriber sub_infrared = handle.subscribe("/mobilebase_arduino/sensor/GP2Y0A41", 100, infrared_callback);
|
|
|
|
|
|
- twist_pub = handle.advertise<geometry_msgs::Twist>("/cmd_vel", 10);
|
|
|
-
|
|
|
- while(ros::ok())
|
|
|
- {
|
|
|
- checkInfraredDist(front_dist, left_dist, right_dist);
|
|
|
+ ros::param::get("~infrared_topic", infrared_topic);
|
|
|
+ ros::param::get("~cmd_topic", cmd_topic);
|
|
|
+ ros::param::get("~linear_speed", linear_speed);
|
|
|
+ ros::param::get("~angular_speed", angular_speed);
|
|
|
+ ros::param::get("~odom_frame", odomFrame);
|
|
|
+ ros::param::get("~base_frame", baseFrame);
|
|
|
|
|
|
- ros::spinOnce();
|
|
|
- loop_rate.sleep();
|
|
|
- }
|
|
|
-
|
|
|
+ ros::Subscriber sub_infrared = handle.subscribe(infrared_topic, 20, infrared_callback);
|
|
|
+ twist_pub = handle.advertise<geometry_msgs::Twist>(cmd_topic, 10);
|
|
|
+
|
|
|
+ ros::spin();
|
|
|
return 0;
|
|
|
}
|