pioneer rosaria 话题读取声呐数据和声呐避障

转载自feiliu的github
原址:https://github.com/drfeiliu/pioneer3_control_ros/blob/master/p3_sonar.cpp
大概流程是订阅话题,然后定义回调函数,回调函数输出数据

/***********************************************
   Data:      2014-04-01
   Author:    Fei Liu
   File:      p3_sonar.cpp
   Function:  Read (subscribe) sonar data and display it on screen
***********************************************/

/*         sensor_msgs/PointCloud
# This message holds a collection of 3d points, plus optional additional
# information about each point.

# Time of sensor data acquisition, coordinate frame ID.
Header header

# Array of 3d points. Each Point32 should be interpreted as a 3d point
# in the frame given in the header.
geometry_msgs/Point32[] points

# Each channel should have the same number of elements as points array,
# and the data in each channel should correspond 1:1 with each point.
# Channel names in common practice are listed in ChannelFloat32.msg.
ChannelFloat32[] channels
*/


/* example of output(using rostopic)
http://docs.ros.org/api/sensor_msgs/html/msg/PointCloud.html
channels: []
---
header: 
  seq: 143
  stamp: 
    secs: 1396372374
    nsecs: 16548440
  frame_id: sonar_frame
points: 

  -1 
    x: 0.0689999982715   //coordination X
    y: 1.19500005245     //coordination Y
    z: 0.0
  -2 
    x: 1.27423167229
    y: 1.50171017647
    z: 0.0
  -3 
    x: 1.08330738544
    y: 0.617999970913
    z: 0.0
  -4 
    x: 1.09762811661
    y: 0.191271170974
    z: 0.0
  -5 
    x: 1.11043059826
    y: -0.193528607488
    z: 0.0
  -6 
    x: 1.12487661839
    y: -0.64200001955
    z: 0.0
  -7 
    x: 1.00040411949
    y: -1.17537534237
    z: 0.0
  -8 
    x: 0.0689999982715
    y: -2.32699990273
    z: 0.0
  -9 
    x: -0.157000005245
    y: -2.35500001907
    z: 0.0
  -10 
    x: -0.578387975693
    y: -0.566369950771
    z: 0.0
  -11 
    x: -0.587740302086
    y: -0.280499994755
    z: 0.0
  -12 
    x: -2.06704616547
    y: -0.346512645483
    z: 0.0
  -13 
    x: -2.0700006485
    y: 0.347033590078
    z: 0.0
  -14 
    x: -1.01555681229
    y: 0.527499973774
    z: 0.0
  -15 
    x: -1.01355516911
    y: 1.08498203754
    z: 0.0
  -16 
    x: -0.157000005245
    y: 1.18700003624
    z: 0.0

*/

/*   reference
http://stanford-ros-pkg.googlecode.com/svn-history/r146/trunk/recyclerbot/src/object_detector_node.cpp

*/

/*******about the rays and distance*******/

//               AT DX front sonar beams
//                      3 4            +/-10 degree
//                   2   ^   5         +/-30 degree
//                 1     |     6       +/-50 degree
//             ___0___center____7____  +/-90 degree
//             |         |          |
//             |         |          |
//             |         |          |
//             |      P3_ROBOT      |
//             |         |          |
//             |         |          |
//             |         |          |
//             |         |          |
//             |         |          |
//             |_________|__________|

// AT distance offset(mm):
//0   1   2   3   4   5   6   7
//160 220 240 240 240 240 220 160
/*******about the rays and distance*******/


#include <ros/ros.h>
#include <sensor_msgs/PointCloud.h>   //for sonar data
#include <math.h>
#include <iostream>

using namespace std;

//in this case, we just use 8 sonars that are in front of the robot
#define SONAR_NUM 8

int offset[SONAR_NUM] ={160, 220, 240, 240, 240, 240, 220, 160};


//sensor_msgs::PointCloud sonarData;
int seq = 0;

int distToObstace[SONAR_NUM];

void get_sonarData_Callback(const sensor_msgs::PointCloud::ConstPtr &sonarScanedData)
{
    float tmpX = 0.0, tmpY=0.0;
    seq = sonarScanedData->header.seq;

    printf("seq of sonar beam  and  distance measured-->\n");
    printf("Frame[%d] :  \n", seq);
    for (int i=0; i<SONAR_NUM; i++)    
    { 
        printf("%d\t",i);
    }
    printf("\n");

    for (int i=0; i<SONAR_NUM; i++)    
    {
        tmpX= sonarScanedData->points[i].x; //coordinate x
        tmpY= sonarScanedData->points[i].y; //coordinate y
        distToObstace[i] = int(sqrt(tmpX*tmpX+tmpY*tmpY)*1000-offset[i]);
        printf("%d\t",distToObstace[i]);
    }
    printf("\n\n");
}


int main(int argc, char** argv)
{
  ros::init(argc, argv, "p3_sonar");
  ros::NodeHandle n;

  //plsease modify the topic name "/RosAria/sonar" according to the robot connected
  ros::Subscriber get_sonar_data = n.subscribe<sensor_msgs::PointCloud>("/RosAria/sonar", 100, get_sonarData_Callback);
  printf("\n********** Sonar Readings: **********\n");

  while (ros::ok())
  {  
               
      ros::Duration(0.2).sleep(); 
    /*ROS消息回调处理函数。它俩通常会出现在ROS的主循环中,程序需要不断调用ros::spin() 或 ros::spinOnce(),两者区别在于前者调用后不会再返回,也就是你的主程序到这儿就不往下执行了,而后者在调用后还可以继续执行之后的程序*/
    //  https://www.cnblogs.com/liu-fa/p/5925381.html
      ros::spinOnce();
  }
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(sonarvalue)


find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  rospy
  sensor_msgs
  std_msgs)


catkin_package(
  INCLUDE_DIRS include
  LIBRARIES sonarvalue
  CATKIN_DEPENDS geometry_msgs  roscpp rospy sensor_msgs std_msgs
  DEPENDS system_lib
)


include_directories(  ${catkin_INCLUDE_DIRS})


add_executable(sonarvalue src/sonar.cpp)
target_link_libraries(sonarvalue    ${catkin_LIBRARIES})

这里写图片描述

robot@ubuntu:~/sonar_pioneer_ws$ rostopic type /RosAria/sonar
sensor_msgs/PointCloud

声呐避障,读取声呐数据,对其排序,然后发布速度消息

#include <stdio.h>
#include <math.h>
#include </usr/local/Aria/include/Aria.h>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Pose.h>
#include "geometry_msgs/PoseStamped.h"
#include <sensor_msgs/PointCloud.h>  //for sonar data
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/point_cloud_conversion.h> // can optionally publish sonar as new type pointcloud2
#include <nav_msgs/Odometry.h>
#include "rosaria/BumperState.h"
#include "tf/tf.h"
#include "tf/transform_listener.h"  //for tf::getPrefixParam
#include <tf/transform_broadcaster.h>
#include "tf/transform_datatypes.h"
#include <dynamic_reconfigure/server.h>
#include <rosaria/RosAriaConfig.h>
#include "std_msgs/Float64.h"
#include "std_msgs/Float32.h"
#include "std_msgs/Int8.h"
#include "std_msgs/Bool.h"
#include "std_srvs/Empty.h"

#include <sstream>


ros::Publisher robot;
geometry_msgs::Twist cmdvel;





void bubblesort(double *array, int length)
{
	int i, j;
	for (i = 0; i < length -1; ++i) 
	{
 
		for (j = 0; j < length - i - 1; ++j) 
		{
			if (array[j] > array[j + 1]) 
				{
					double tmp = array[j];
					array[j] = array[j + 1];
					array[j + 1] = tmp;
				}
		}
	}
}



void readSonar(const sensor_msgs::PointCloud::ConstPtr& msg, sensor_msgs::PointCloud *pointCloud)
{
	int i, new_position;
	double data[8];
	double old_data[8];
//一份数据保存两份,old备份,data排序
	for(i = 0; i<8 ; i++)
	{
		data[i]=msg->points[i].x;
		ROS_INFO("I heard sonar: [%lf]", data[i]);
		old_data[i]=data[i];
	}


      	for(int i=0 ; i<8; i++){printf("the old data are: [%lf]\n",old_data[i]);}


	bubblesort(data,8);

      	for(int i=0 ; i<8; i++){printf("__the new data are__: [%lf]\n",data[i]);}

//找到距离最大的声呐位置
	for(int i=0 ; i<8; i++)
	{
		if(old_data[i]==data[7])
		{
			new_position=i;
			ROS_INFO("the new position is: [%d]\n",new_position);
		}
	}

 //外层的if-else,如果距离小于2.5则应该stop
	if((data[7]>2.5))
	{
        //障碍物在前面
		if((new_position==3)or(new_position==4))
		{
			cmdvel.linear.x=0.1;
			cmdvel.angular.z=0.0;
			printf("straight\n");
		}
        //障碍物在左侧
		if((new_position==1)or(new_position==2)or(new_position==3))
		{
			cmdvel.linear.x=0.0;
			cmdvel.angular.z=0.1;
			printf("left\n");
		}
		else if((new_position==4)or(new_position==5)or(new_position==6))
		{
			cmdvel.linear.x=0.0;
			cmdvel.angular.z=-0.1;
			printf("right\n");
		}
	}
	else
	{
		cmdvel.linear.x=0.0;
		cmdvel.angular.z=0.0;
		printf("stop\n");
	}
	
	robot.publish(cmdvel);
}



int main(int argc, char **argv)
{
	ros::init(argc, argv, "sonar_obstacles_avoidance");

	ros::NodeHandle n;
	ros::NodeHandle nh;
	//sensor_msgs::Joy joyData;
	sensor_msgs::PointCloud pointCloud;
	
	//ros::Subscriber realJoystick = n.subscribe<sensor_msgs::Joy>("joy", 1000, boost::bind(readJoy, _1, &joyData));
	ros::Subscriber sonar = n.subscribe<sensor_msgs::PointCloud>("/RosAria/sonar", 1000, boost::bind(readSonar, _1, &pointCloud));
	//robot = n.advertise<sensor_msgs::Joy>("robot", 1000);
        robot = nh.advertise<geometry_msgs::Twist>("/RosAria/cmd_vel", 1000);
	
	ros::Rate loop_rate(100);

	
	while (ros::ok())
	{

		
		loop_rate.sleep();
			

		ros::spinOnce();
	}
	



	return 0;
}



		/*if(msg->points[i].x < 0.5){
			cmdvel.linear.x=0.0;
			cmdvel.linear.y=0.0;
			cmdvel.linear.z=0.0;
			cmdvel.angular.x=0.0;
			cmdvel.angular.y=0.0;
			cmdvel.angular.z=0.0;
		}
		*/


/*
			if((i==3)or(i==4))
			{
				cmdvel.linear.x=0.1;
				cmdvel.angular.z=0.0;
				printf("straight\n");
			}
			else if((i==1)or(i==2))
			{
				cmdvel.linear.x=0.0;
				cmdvel.angular.z=0.1;
				printf("left\n");
			}
			else if((i==5)or(i==6))
			{
				cmdvel.linear.x=0.0;
				cmdvel.angular.z=-0.1;
				printf("right\n");
			}
			else if((i==11)or(i==12))
			{
				cmdvel.linear.x=-0.1;
				cmdvel.angular.z=0.0;
				printf("backstraight\n");
			}
			else if((i==9)or(i==10))
			{
				cmdvel.linear.x=0.0;
				cmdvel.angular.z=-0.1;
				printf("right\n");			
			}
			else if((i==13)or(i==14))
			{
				cmdvel.linear.x=0.0;
				cmdvel.angular.z=-0.1;
				printf("left\n");
			}
			else
			{
				cmdvel.linear.x=0.0;
				cmdvel.angular.z=0.0;
				printf("stop\n");			
			}
		*/


猜你喜欢

转载自blog.csdn.net/qq_35508344/article/details/78784534