Browse Source

添加走正方形和圆形小程序

adam_zhuo 3 years ago
parent
commit
196878a346

+ 39 - 0
.vscode/c_cpp_properties.json

@@ -0,0 +1,39 @@
+{
+  "configurations": [
+    {
+      "browse": {
+        "databaseFilename": "",
+        "limitSymbolsToIncludedHeaders": true
+      },
+      "includePath": [
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/devel/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_vision_ws/devel/include/**",
+        "/opt/ros/melodic/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/amcl/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/base_local_planner/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/carrot_planner/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/clear_costmap_recovery/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/costmap_2d/include/**",
+        "/home/ssfz/cv_bridge_ws/src/vision_opencv/cv_bridge/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/dwa_local_planner/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/global_planner/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_camera/gscam/include/**",
+        "/home/ssfz/cv_bridge_ws/src/vision_opencv/image_geometry/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/map_server/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/move_base/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/move_slow_and_clear/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/nav_core/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/navfn/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/qingzhou_odom/qingzhou_bringup/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/qingzhou_odom/robot_pose_ekf/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_race/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/rotate_recovery/include/**",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/src/robot_navagition/voxel_grid/include/**",
+        "/usr/include/**",
+        "/home/ssfz/work/ssfz/panda_ws/src/**"
+      ],
+      "name": "ROS"
+    }
+  ],
+  "version": 4
+}

+ 83 - 0
.vscode/settings.json

@@ -0,0 +1,83 @@
+{
+    "python.autoComplete.extraPaths": [
+        "/home/ssfz/cv_bridge_ws/devel/lib/python3/dist-packages",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/devel/lib/python2.7/dist-packages",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_vision_ws/devel/lib/python2.7/dist-packages",
+        "/opt/ros/melodic/lib/python2.7/dist-packages"
+    ],
+    "python.analysis.extraPaths": [
+        "/home/ssfz/cv_bridge_ws/devel/lib/python3/dist-packages",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_ws/devel/lib/python2.7/dist-packages",
+        "/home/ssfz/work/ssfz/qingzhou/qingzhou_vision_ws/devel/lib/python2.7/dist-packages",
+        "/opt/ros/melodic/lib/python2.7/dist-packages"
+    ],
+    "files.associations": {
+        "*.h": "cpp",
+        "cctype": "cpp",
+        "clocale": "cpp",
+        "cmath": "cpp",
+        "csignal": "cpp",
+        "cstdarg": "cpp",
+        "cstddef": "cpp",
+        "cstdio": "cpp",
+        "cstdlib": "cpp",
+        "cstring": "cpp",
+        "ctime": "cpp",
+        "cwchar": "cpp",
+        "cwctype": "cpp",
+        "any": "cpp",
+        "array": "cpp",
+        "atomic": "cpp",
+        "strstream": "cpp",
+        "*.tcc": "cpp",
+        "bitset": "cpp",
+        "chrono": "cpp",
+        "cinttypes": "cpp",
+        "complex": "cpp",
+        "condition_variable": "cpp",
+        "cstdint": "cpp",
+        "deque": "cpp",
+        "forward_list": "cpp",
+        "list": "cpp",
+        "unordered_map": "cpp",
+        "unordered_set": "cpp",
+        "vector": "cpp",
+        "exception": "cpp",
+        "algorithm": "cpp",
+        "functional": "cpp",
+        "iterator": "cpp",
+        "map": "cpp",
+        "memory": "cpp",
+        "memory_resource": "cpp",
+        "numeric": "cpp",
+        "optional": "cpp",
+        "random": "cpp",
+        "ratio": "cpp",
+        "set": "cpp",
+        "string": "cpp",
+        "string_view": "cpp",
+        "system_error": "cpp",
+        "tuple": "cpp",
+        "type_traits": "cpp",
+        "utility": "cpp",
+        "hash_map": "cpp",
+        "hash_set": "cpp",
+        "fstream": "cpp",
+        "initializer_list": "cpp",
+        "iomanip": "cpp",
+        "iosfwd": "cpp",
+        "iostream": "cpp",
+        "istream": "cpp",
+        "limits": "cpp",
+        "mutex": "cpp",
+        "new": "cpp",
+        "ostream": "cpp",
+        "sstream": "cpp",
+        "stdexcept": "cpp",
+        "streambuf": "cpp",
+        "thread": "cpp",
+        "cfenv": "cpp",
+        "typeindex": "cpp",
+        "typeinfo": "cpp"
+    }
+}

+ 11 - 0
src/robot_demo/CMakeLists.txt

@@ -10,6 +10,7 @@ add_compile_options(-std=c++11)
 ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
 ## is used, also find other catkin packages
 find_package(catkin REQUIRED COMPONENTS
+  tf
   roscpp
   std_msgs
   sensor_msgs
@@ -146,6 +147,8 @@ add_executable(${PROJECT_NAME}_color_node
 
 add_executable(${PROJECT_NAME}_imu_node src/imu_demo_node.cpp)
 add_executable(${PROJECT_NAME}_infrared_node src/infrared_demo_node.cpp)
+add_executable(${PROJECT_NAME}_drive_circle_node src/drive_circle_node.cpp)
+add_executable(${PROJECT_NAME}_drive_square_node src/drive_square_node.cpp)
 
 
 ## Rename C++ executable without prefix
@@ -176,6 +179,14 @@ target_link_libraries(${PROJECT_NAME}_infrared_node
    ${catkin_LIBRARIES}
 )
 
+target_link_libraries(${PROJECT_NAME}_drive_circle_node
+   ${catkin_LIBRARIES}
+)
+
+target_link_libraries(${PROJECT_NAME}_drive_square_node
+   ${catkin_LIBRARIES}
+)
+
 #############
 ## Install ##
 #############

+ 13 - 0
src/robot_demo/cfg/drive_circle.yaml

@@ -0,0 +1,13 @@
+#####################################################
+# Copyright: 2016-2021 www.corvin.cn ROS小课堂
+# Description:测试走圆形小程序
+#   angular_speed:角速度.
+#   linear_speed:线速度.
+# Author: adam_zhuo
+# History:
+#   20210512:init this file.
+######################################################
+
+angular_speed: 0.6
+linear_speed: 0.2
+

+ 18 - 0
src/robot_demo/cfg/drive_square.yaml

@@ -0,0 +1,18 @@
+#####################################################
+# Copyright: 2016-2021 www.corvin.cn ROS小课堂
+# Description:测试走正方形小程序
+#   angular_speed:角速度.
+#   linear_speed:线速度.
+#   square_side_length:正方形边长.
+# Author: adam_zhuo
+# History:
+#   20210512:init this file.
+######################################################
+
+odom_frame: /odom_combined
+base_frame: /base_footprint
+
+square_side_length: 0.3
+angular_speed: 0.6
+linear_speed: 0.2
+

+ 32 - 0
src/robot_demo/include/drive_circle.h

@@ -0,0 +1,32 @@
+/*
+ * @Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
+ * @Author: adam_zhuo
+ * @Date: 2021-08-02 14:26:22
+ * @Description: file content
+ * @History: 20210429:-adam_zhuo
+ */
+
+#ifndef _DRIVE_CIRCLE_H
+#define _DRIVE_CIRCLE_H
+
+#include <ros/ros.h>
+#include <tf/transform_listener.h>
+#include <std_msgs/Float32.h>
+#include <geometry_msgs/Twist.h>
+
+class Drive_Circle
+{
+private:
+    float angular_speed;
+    float linear_speed;
+    ros::NodeHandle nh;
+    ros::Publisher _cmd_vel_pub;
+    geometry_msgs::Twist twist;
+public:
+    Drive_Circle();
+    ~Drive_Circle();
+    void publish_twist_cmd(float x, float z);
+    void go();
+};
+
+#endif

+ 37 - 0
src/robot_demo/include/drive_square.h

@@ -0,0 +1,37 @@
+/*
+ * @Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
+ * @Author: adam_zhuo
+ * @Date: 2021-08-02 11:41:00
+ * @Description: file content
+ * @History: 20210429:-adam_zhuo
+ */
+
+#ifndef _DRIVE_SQUARE_H
+#define _DRIVE_SQUARE_H
+
+#include <ros/ros.h>
+#include <tf/transform_listener.h>
+#include <std_msgs/Float32.h>
+#include <geometry_msgs/Twist.h>
+
+class Drive_Square
+{
+private:
+    float square_side_length;
+    float angular_speed;
+    float linear_speed;
+    std::string odom_frame;
+    std::string base_frame;
+    ros::NodeHandle nh;
+    ros::Publisher _cmd_vel_pub;
+    geometry_msgs::Twist twist;
+public:
+    Drive_Square();
+    ~Drive_Square();
+    void go_forward(const float square_side_length);
+    void go_circle();
+    void publish_twist_cmd(float x, float z);
+    void go();
+};
+
+#endif

+ 17 - 0
src/robot_demo/launch/drive_circle.launch

@@ -0,0 +1,17 @@
+<!--
+ * @Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
+ * @Author: adam_zhuo
+ * @Date: 2021-04-30 11:16:35
+ * @Description: 启动走圆形节点
+ * @History: 20210430:初始化文件-adam_zhuo
+-->
+<launch>
+
+  <!-- 加载参数 -->
+  <arg name="cfg_file" default="$(find robot_demo)/cfg/drive_circle.yaml" />
+
+  <!-- 启动drive_circle_node -->
+  <node pkg="robot_demo" type="robot_demo_drive_circle_node" name="drive_circle_node" output="screen">
+    <rosparam file="$(arg cfg_file)" command="load" />
+  </node>
+</launch>

+ 17 - 0
src/robot_demo/launch/drive_square.launch

@@ -0,0 +1,17 @@
+<!--
+ * @Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
+ * @Author: adam_zhuo
+ * @Date: 2021-04-30 11:16:35
+ * @Description: 启动走正方形节点
+ * @History: 20210430:初始化文件-adam_zhuo
+-->
+<launch>
+
+  <!-- 加载参数 -->
+  <arg name="cfg_file" default="$(find robot_demo)/cfg/drive_square.yaml" />
+
+  <!-- 启动drive_square_node -->
+  <node pkg="robot_demo" type="robot_demo_drive_square_node" name="drive_square_node" output="screen">
+    <rosparam file="$(arg cfg_file)" command="load" />
+  </node>
+</launch>

+ 3 - 0
src/robot_demo/package.xml

@@ -55,18 +55,21 @@
   <build_depend>cv_bridge</build_depend>
   <build_depend>sensor_msgs</build_depend>
   <build_depend>geometry_msgs</build_depend>
+  <build_depend>tf</build_depend>
   <build_export_depend>roscpp</build_export_depend>
   <build_export_depend>std_msgs</build_export_depend>
   <build_export_depend>ros_arduino_msgs</build_export_depend>
   <build_export_depend>cv_bridge</build_export_depend>
   <build_export_depend>sensor_msgs</build_export_depend>
   <build_export_depend>geometry_msgs</build_export_depend>
+  <build_export_depend>tf</build_export_depend>
   <exec_depend>roscpp</exec_depend>
   <exec_depend>std_msgs</exec_depend>
   <exec_depend>ros_arduino_msgs</exec_depend>
   <exec_depend>cv_bridge</exec_depend>
   <exec_depend>sensor_msgs</exec_depend>
   <exec_depend>geometry_msgs</exec_depend>
+  <exec_depend>tf</exec_depend>
 
 
   <!-- The export tag contains other, unspecified, tags -->

+ 45 - 0
src/robot_demo/src/drive_circle_node.cpp

@@ -0,0 +1,45 @@
+/*
+ * @Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
+ * @Author: adam_zhuo
+ * @Date: 2021-08-02 14:26:07
+ * @Description: file content
+ * @History: 20210429:-adam_zhuo
+ */
+#include "drive_circle.h"
+
+Drive_Circle::Drive_Circle(){
+    ros::param::param<float>("~angular_speed", angular_speed, 0.2);
+    ros::param::param<float>("~linear_speed", linear_speed, 0.2);
+    _cmd_vel_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 1);
+    Drive_Circle::go();
+}
+
+Drive_Circle::~Drive_Circle(){
+
+}
+
+void Drive_Circle::publish_twist_cmd(float x, float z){
+    twist.linear.x = x;
+    twist.angular.z = z;
+    _cmd_vel_pub.publish(twist);
+}
+
+void Drive_Circle::go(){
+    while (ros::ok())
+    {
+        publish_twist_cmd(linear_speed, angular_speed);
+        ros::Duration(0.2).sleep();
+    }
+}
+
+int main(int argc, char **argv)
+{
+    //初始化节点
+    ros::init(argc, argv, "drive_circle_node");
+
+    //根据Drive_Circle声明对象,调用构造函数
+    Drive_Circle drive_circle;
+
+    //使ROS中回调函数生效
+    ros::spin();
+}

+ 0 - 369
src/robot_demo/src/drive_square.cpp

@@ -1,369 +0,0 @@
-/***************************************************************
- Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
- Description:控制两轮小车走一个正方形,正方形的边长可以通过配置
-   文件来配置.
- Author: corvin
- History:
-    20210717:init this code.
- **************************************************************/
-#include <ros/ros.h>
-#include <std_msgs/Float32.h>
-#include <nav_msgs/Odometry.h>
-#include <geometry_msgs/Twist.h>
-#include <tf/transform_listener.h>
-#include "rasp_imu_hat_6dof/GetYawData.h"
-
-
-#define  GO_FORWARD   0
-#define  TURN_LEFT    1
-#define  TURN_RIGHT   2
-#define  TURN_BACK    3
-#define  HORIZ_MOVE   4
-
-#define  ERROR       -1
-
-//global variable
-ros::Publisher twist_pub;
-ros::ServiceClient yawSrvClient;
-rasp_imu_hat_6dof::GetYawData yawSrv;
-
-//红外测距相关的服务
-ros::ServiceClient distSrvClient;
-ros_arduino_msgs::GetInfraredDistance distSrv;
-
-float warn_dist = 0.25;  //warn check distance
-float tolerance_dist = 0.05; //对警告距离的容忍值
-float forward_dist = 0.50; //每次前进移动时走的距离
-
-std::string odomFrame;
-std::string baseFrame;
-
-float linear_x_speed = 0.27;
-float angular_speed = 1.0;
-
-float start_yaw_data = 0.0;
-int turnFlag = ERROR;
-
-/*********************************************************
- * Descripition: 发布控制移动的消息,这里对于平面移动的
- *   机器人只需要控制linear_x和angular_z即可.
- ********************************************************/
-void publishTwistCmd(float linear_x, float angular_z)
-{
-    geometry_msgs::Twist twist_msg;
-
-    twist_msg.linear.x = linear_x;
-    twist_msg.linear.y = 0.0;
-    twist_msg.linear.z = 0.0;
-
-    twist_msg.angular.x = 0.0;
-    twist_msg.angular.y = 0.0;
-    twist_msg.angular.z = angular_z;
-
-    twist_pub.publish(twist_msg);
-}
-
-/**********************************************************
- * Description:调用IMU板发布出来的yaw信息,可以根据该数据
- *   来修正转弯时不准确的问题.注意这里的yaw数据为弧度值.
- *   注意往右旋转为负值,左旋转为正值.右手定则.
- *   注意在ROS中IMU数据中yaw的范围,具体表示如下:
- *                0  -0
- *                -----
- *              /      \
- *         1.57|        | -1.57
- *              \      /
- *               ------
- *             3.14 -3.14
- **********************************************************/
-void yawUpdate(const float start_yaw)
-{
-    float target = 0.0;
-    float diff = 10.0;
-    float angular = 0.0;
-    float now_yaw = 0.0;
-
-    //开始计算修正后的目标角度
-    if((turnFlag == GO_FORWARD)||(turnFlag == HORIZ_MOVE))
-    {
-        target = start_yaw;
-    }
-    else if(turnFlag == TURN_LEFT)
-    {
-        target = start_yaw + M_PI/2.0;
-        if(target > M_PI)
-        {
-            target = target - M_PI*2.0;
-        }
-    }
-    else if(turnFlag == TURN_RIGHT)
-    {
-        target = start_yaw - M_PI/2.0;
-        if(target < -M_PI)
-        {
-            target = target + M_PI*2.0;
-        }
-    }
-    else //turn back
-    {
-        target = start_yaw + M_PI;
-        if(target > M_PI)
-        {
-            target = target - M_PI*2.0;
-        }
-    }
-
-    //开始不断的计算偏差,调整角度
-    while(fabs(diff) > 0.01)
-    {
-        yawSrvClient.call(yawSrv);
-        now_yaw = yawSrv.response.yaw;
-        ROS_INFO("Now Yaw data:%f, Target Yaw:%f", now_yaw, target);
-
-        diff = target - now_yaw;
-        if(diff > 0)
-        {
-            angular = angular_speed;
-        }
-        else
-        {
-            angular = -angular_speed;
-        }
-        ROS_WARN("Yaw diff:%f, angular:%f", diff, angular);
-        publishTwistCmd(0, angular);
-        ros::Duration(0.04).sleep();
-    }
-    publishTwistCmd(0, 0); //在修正角度结束后应该立刻停止小车转动
-    ROS_INFO("Correct Yaw diff over !");
-}
-
-/****************************************************
- * Description:控制小车前进移动0.5m
- ***************************************************/
-void goForward(const float check_dist)
-{
-    tf::TransformListener tf_Listener;
-    tf::StampedTransform tf_Transform;
-    float dist = 0.0; //每次前进移动的距离
-    float front_dist = 0.0;
-
-    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();
-
-    distSrvClient.call(distSrv); //通过服务调用来获取测距值
-    front_dist = distSrv.response.front_dist; //记录当前测距值,防止撞墙
-    ROS_INFO("Front dist:%f", front_dist);
-    while((dist<check_dist)&&(front_dist>tolerance_dist*4.0)&&(ros::ok()))
-    {
-        ROS_INFO("Go forward, dist:%f", dist);
-        publishTwistCmd(linear_x_speed, 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));
-
-        distSrvClient.call(distSrv); //通过服务调用来获取测距值
-        front_dist = distSrv.response.front_dist; //记录当前测距值,防止撞墙
-        ROS_INFO("Front dist:%f", front_dist);
-    }
-    publishTwistCmd(0, 0); //stop move
-    ROS_INFO("Go forward finish !!!");
-}
-
-/*************************************************************
- * Description:控制小车左右转90度,或者掉头180度.这里实现小车
- *   转弯功能是通过不断监听odom和base_link之间的tf转换完成的.
- ************************************************************/
-int controlTurn(int flag)
-{
-    tf::TransformListener tf_Listener;
-    tf::StampedTransform tf_Transform;
-    float angular = 0.0;
-    float check_angle = 0.0;
-
-    switch(flag)
-    {
-        case TURN_LEFT: //向左转动90°
-            turnFlag = TURN_LEFT;
-            angular = angular_speed;
-            check_angle = M_PI/2.0;
-            break;
-
-        case TURN_RIGHT: //向右转动90°
-            turnFlag = TURN_RIGHT;
-            angular = -angular_speed;
-            check_angle = M_PI/2.0;
-            break;
-
-        case TURN_BACK: //小车原地掉头180度
-            turnFlag = TURN_BACK;
-            check_angle = M_PI;
-            angular = angular_speed;
-            break;
-
-        case GO_FORWARD: //小车直行50cm
-            goForward(forward_dist);
-            return 1;
-
-        default:
-            ROS_ERROR("Turn flag error !");
-            return -1;
-    }
-
-    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();
-
-        return -2;
-    }
-
-    //ROS_INFO("Check_angle:%f, angular_speed:%f",check_angle, angular);
-    tf_Listener.lookupTransform(odomFrame, baseFrame, ros::Time(0), tf_Transform);
-    float last_angle = fabs(tf::getYaw(tf_Transform.getRotation()));
-    float turn_angle = 0.0;
-    ROS_INFO("first_angle:%f", last_angle);
-    while((fabs(turn_angle) < check_angle)&&(ros::ok()))
-    {
-        publishTwistCmd(0, angular); //原地转弯,不需要linear_x,y的控制
-        ros::Duration(0.10).sleep(); //100 ms
-
-        try
-        {
-            tf_Listener.lookupTransform(odomFrame, baseFrame, ros::Time(0), tf_Transform);
-        }
-        catch(tf::TransformException &ex)
-        {
-            ROS_ERROR("%s", ex.what());
-            continue;
-        }
-        float rotation = fabs(tf::getYaw(tf_Transform.getRotation()));
-        float delta_angle = fabs(rotation - last_angle);
-
-        turn_angle += delta_angle;
-        last_angle = rotation;
-        ROS_INFO("Turn angle:%f", turn_angle);
-    }
-    publishTwistCmd(0, 0); //原地转弯完成后,需要立刻停止小车的旋转
-    ROS_INFO("Turning finish !!!");
-    ros::Duration(0.1).sleep(); //100 ms
-
-    return 0;
-}
-
-/***************************************************************************
- * Description:检查三个传感器数据,然后控制小车移动.这里需要防止小车在原地
- *   进行连续两次旋转,在每次转弯后必须有个直行.这里需要注意的是当小车在转弯
- *   后一定要有一个可以修正转弯角度的功能,否则转弯后角度不准确小车前进方向
- *   会错.这里的走迷宫策略是左转优先,中间是直行,最后是右转.
- *   当前方,左边,右边都无法移动时,进行掉头动作,然后直行.
- **************************************************************************/
-void checkInfraredDist(float infrared_f,float infrared_l,float infrared_r,
-        float tolerance, float warn_distance)
-{
-    static int flag = 0; //记录是否转过弯的标志
-
-    yawSrvClient.call(yawSrv); //通过服务调用来获取yaw值
-    start_yaw_data = yawSrv.response.yaw; //记录当前yaw值,用于后面修正
-
-    //判断能否左转,并且上一次动作不能是转弯
-    if((infrared_l == (float)0.3)&&(flag != 1))
-    {
-        ROS_WARN("turn Left! yaw_data:%f", start_yaw_data);
-        turnFlag = TURN_LEFT;
-        flag = 1; //设置转弯标志
-    }
-    else if(infrared_f > warn_distance)//判断能否直行
-    {
-        //始终控制小车保持在过道的中间位置
-        ROS_WARN("go Forward ! yaw_data: %f", start_yaw_data);
-        turnFlag = GO_FORWARD;
-        flag = 0; //设置直行标志
-    }
-    else if((infrared_r == (float)0.3)&&(flag != 1))//判断能否右转
-    {
-        ROS_WARN("turn Right ! yaw_data: %f", start_yaw_data);
-        turnFlag = TURN_RIGHT;
-        flag = 1; //设置转弯标志
-    }
-    else //小车掉头
-    {
-        ROS_WARN("turn Back ! yaw_data: %f", start_yaw_data);
-        turnFlag = TURN_BACK;
-    }
-
-    controlTurn(turnFlag); //开始执行动作
-}
-
-/*****************************************************************************
- * Description: 订阅红外测距传感器话题后的回调函数,根据三个传感器数据进行走
- *   迷宫.
- ****************************************************************************/
-void infrared_callback(const ros_arduino_msgs::InfraredSensors::ConstPtr& msg)
-{
-    ROS_INFO("front left right distance:[%f %f %f]", msg->front_dist,
-            msg->left_dist, msg->right_dist);
-    front_dist = msg->front_dist;
-    left_dist  = msg->left_dist;
-    right_dist = msg->right_dist;
-
-    //根据三个传感器反馈的测距值开始移动
-    checkInfraredDist(front_dist, left_dist, right_dist, tolerance_dist, warn_dist);
-    yawUpdate(start_yaw_data); //移动完成后开始更新yaw值
-}
-
-/************************************************************
- * Description:主函数初始化节点,读取配置参数,订阅和发布话题,
- *   在订阅的红外测距数据话题回调函数中进行移动,通过调用yaw
- *   服务进行转弯角度的修正.
- ************************************************************/
-int main(int argc, char **argv)
-{
-    std::string cmd_topic;
-    std::string yaw_service;
-    std::string yaw_zero_service;
-
-    ros::ServiceClient yawZeroClient;
-
-    ros::init(argc, argv, "drive_square_node");
-    ros::NodeHandle handle;
-
-    ros::param::get("~cmd_topic", cmd_topic);
-    ros::param::get("~yaw_service", yaw_service);
-    ros::param::get("~yaw_zero_service", yaw_zero_service);
-    ros::param::get("~linear_x",  linear_x_speed);
-    ros::param::get("~tolerance_dist", tolerance_dist);
-    ros::param::get("~odom_frame", odomFrame);
-    ros::param::get("~base_frame", baseFrame);
-
-    twist_pub = handle.advertise<geometry_msgs::Twist>(cmd_topic, 1);
-    yawSrvClient = handle.serviceClient<rasp_imu_hat_6dof::GetYawData>(yaw_service);
-
-    yawZeroClient = handle.serviceClient<rasp_imu_hat_6dof::SetYawZero>(yaw_zero_service);
-    rasp_imu_hat_6dof::SetYawZero yawZeroSrv;
-    yawZerlient.call(yawZeroSrv);
-    ROS_INFO("IMU yaw data zero");
-
-    ros::spin();
-    return 0;
-}
-

+ 128 - 0
src/robot_demo/src/drive_square_node.cpp

@@ -0,0 +1,128 @@
+/*
+ * @Copyright(C): 2016-2021 ROS小课堂 www.corvin.cn
+ * @Author: adam_zhuo
+ * @Date: 2021-08-02 11:40:00
+ * @Description: file content
+ * @History: 20210429:-adam_zhuo
+ */
+#include "drive_square.h"
+
+Drive_Square::Drive_Square(){
+    ros::param::param<std::string>("~odom_frame", odom_frame, "odom");
+    ros::param::param<std::string>("~base_frame", base_frame, "base_link");
+    ros::param::param<float>("~angular_speed", angular_speed, 0.2);
+    ros::param::param<float>("~linear_speed", linear_speed, 0.2);
+    ros::param::param<float>("~square_side_length", square_side_length, 0.2);
+    _cmd_vel_pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 1);
+    go();
+}
+
+Drive_Square::~Drive_Square(){
+
+}
+
+void Drive_Square::publish_twist_cmd(float x, float z){
+    twist.linear.x = x;
+    twist.angular.z = z;
+    _cmd_vel_pub.publish(twist);
+}
+
+void Drive_Square::go_forward(const float square_side_length){
+    tf::TransformListener tf_Listener;
+    tf::StampedTransform tf_Transform;
+    float dist = 0.0; //每次前进移动的距离
+
+    try
+    {
+        tf_Listener.waitForTransform(odom_frame, base_frame, 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(odom_frame, base_frame, ros::Time(0), tf_Transform);
+    float x_start = tf_Transform.getOrigin().x();
+    float y_start = tf_Transform.getOrigin().y();
+
+    while((dist < square_side_length)&&(ros::ok()))
+    {
+        ROS_INFO("Go forward, dist:%f", dist);
+        publish_twist_cmd(linear_speed, 0);
+        ros::Duration(0.10).sleep(); //100 ms
+
+        tf_Listener.lookupTransform(odom_frame, base_frame, 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));
+    }
+    publish_twist_cmd(0, 0); //stop move
+    ROS_INFO("Go forward finish !!!");
+}
+
+void Drive_Square::go_circle(){
+    tf::TransformListener tf_Listener;
+    tf::StampedTransform tf_Transform;
+    float check_angle = M_PI / 2.0;
+    try
+    {
+        tf_Listener.waitForTransform(odom_frame, base_frame, 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(odom_frame, base_frame, ros::Time(0), tf_Transform);
+    float last_angle = fabs(tf::getYaw(tf_Transform.getRotation()));
+    float turn_angle = 0.0;
+    ROS_INFO("first_angle:%f", last_angle);
+    while((fabs(turn_angle) < check_angle)&&(ros::ok()))
+    {
+        publish_twist_cmd(0, angular_speed); //原地转弯,不需要linear_x,y的控制
+        ros::Duration(0.10).sleep(); //100 ms
+
+        try
+        {
+            tf_Listener.lookupTransform(odom_frame, base_frame, ros::Time(0), tf_Transform);
+        }
+        catch(tf::TransformException &ex)
+        {
+            ROS_ERROR("%s", ex.what());
+            continue;
+        }
+        float rotation = fabs(tf::getYaw(tf_Transform.getRotation()));
+        float delta_angle = fabs(rotation - last_angle);
+
+        turn_angle += delta_angle;
+        last_angle = rotation;
+        ROS_INFO("Turn angle:%f", turn_angle);
+    }
+    publish_twist_cmd(0, 0); //原地转弯完成后,需要立刻停止小车的旋转
+    ROS_INFO("Turning finish !!!");
+    ros::Duration(0.1).sleep(); //100 ms
+}
+
+void Drive_Square::go(){
+    for (size_t i = 0; i < 4; i++)
+    {
+        Drive_Square::go_forward(square_side_length);
+        Drive_Square::go_circle();
+    }
+}
+
+int main(int argc, char **argv)
+{
+    //初始化节点
+    ros::init(argc, argv, "drive_square_node");
+
+    //根据Drive_Square声明对象,调用构造函数
+    Drive_Square drive_square;
+
+    //使ROS中回调函数生效
+    ros::spin();
+}