00001
00002
00003 #include <ros/ros.h>
00004 #include <pcl_ros/point_cloud.h>
00005 #include <pcl/point_types.h>
00006 #include "pcl/io/pcd_io.h"
00007
00008 #include <algorithm>
00009 #include <cmath>
00010 #include <iostream>
00011
00012 #include "Eigen/Dense"
00013
00014 #include "Vector3.h"
00015 #include "ClearpathDemoTools.h"
00016
00017 #include "geometry_msgs/Twist.h"
00018 #include "turtlebot_node/SetTurtlebotMode.h"
00019
00020
00021 #define MAX_RUNTIME_SECONDS 0.1f
00022
00023
00024 typedef pcl::PointXYZRGB PointType;
00025 typedef pcl::PointCloud<PointType> PCLPointCloud;
00026
00027
00028 ros::Publisher pubvel;
00029
00030
00031 double lin_speed = 0.3;
00032 double ang_speed = 0.75;
00033 double still_ang_speed = 2.0;
00034 double cam_height = 0.55;
00035 double stop_distance = 0.8;
00036 int stop_point_count = 50;
00037
00038
00039 bool normal_initialized = false;
00040 double base_normal[4] = {0.0};
00041 double last_normal[4] = {0.0};
00042
00043
00044 PointCloud cloudCopy;
00045 PointCloud cloudCut;
00046 PointCloud upright;
00047 PointCloud slice;
00048
00049
00050 double start_command = 0.0;
00051 double turn_time = 0.0;
00052
00053
00054 double my_ang_speed = 0.0;
00055 bool stop_mode = false;
00056
00057
00058 void callback(const PCLPointCloud::ConstPtr& cloud)
00059 {
00060
00061 cloudCopy.points.clear();
00062 cloudCut.points.clear();
00063 upright.points.clear();
00064 slice.points.clear();
00065
00066
00067 ros::Time begin = ros::Time::now();
00068
00069
00070
00071 for (int i = 0; i < cloud->points.size(); i++)
00072 {
00073 Point p; p.x = cloud->points[i].x; p.y = cloud->points[i].y; p.z = cloud->points[i].z; p.rgb = cloud->points[i].rgb;
00074 cloudCopy.points.push_back(p);
00075 }
00076
00077
00078 if (normal_initialized == false)
00079 {
00080
00081 ClearpathDemoTools::VerticalCut(&cloudCopy, &cloudCut, base_normal[3]-0.3, base_normal[3]+0.3, 13);
00082
00083
00084 double norm[4];
00085 norm[0] = last_normal[0]; norm[1] = last_normal[1]; norm[2] = last_normal[2]; norm[3] = last_normal[3];
00086 if ( ClearpathDemoTools::PlaneRANSAC(&cloudCut, &norm[0], true) ) {
00087 ClearpathDemoTools::PlaneLS(&cloudCut, &norm[0]);
00088 last_normal[0] = norm[0]; last_normal[1] = norm[1]; last_normal[2] = norm[2]; last_normal[3] = norm[3];
00089 normal_initialized = true;
00090 }
00091 }
00092
00093
00094 ClearpathDemoTools::TransformByNormal(&cloudCopy, &upright, &last_normal[0]);
00095
00096
00097 ClearpathDemoTools::VerticalCut(&upright, &slice, -1.0, -0.02, 1);
00098
00099
00100 unsigned closeCount = 0;
00101 for ( int i = 0; i < slice.points.size(); i++ )
00102 {
00103 double d = sqrt(slice.points[i].x*slice.points[i].x + slice.points[i].z*slice.points[i].z);
00104 if ( d < stop_distance )
00105 closeCount++;
00106 }
00107
00108
00109 geometry_msgs::Twist tw;
00110 tw.linear.x = 0.0;
00111 tw.angular.z = 0.0;
00112
00113 if (stop_mode == true)
00114 {
00115 if (ros::Time::now().toSec() - start_command > turn_time)
00116 {
00117 stop_mode = false;
00118 my_ang_speed = 0.0;
00119 }
00120 }
00121 else
00122 {
00123
00124 srand ( time(NULL) );
00125 int rndm2 = rand() % 2;
00126 int rndm3 = rand() % 3 - 1;
00127
00128 if (closeCount > stop_point_count)
00129 {
00130 stop_mode = true;
00131
00132
00133 if (rndm2 == 1) my_ang_speed = still_ang_speed;
00134 else my_ang_speed = -still_ang_speed;
00135
00136
00137 start_command = ros::Time::now().toSec();
00138
00139
00140 turn_time = double(rand() % 3 + 1)*0.5;
00141 }
00142 else
00143 {
00144
00145 if (ros::Time::now().toSec() - start_command > 1.0)
00146 {
00147 my_ang_speed = rndm3*ang_speed;
00148 start_command = ros::Time::now().toSec();
00149 }
00150
00151
00152 tw.linear.x = lin_speed;
00153 }
00154 }
00155
00156
00157 tw.angular.z = my_ang_speed;
00158 pubvel.publish(tw);
00159
00160 ros::Duration duration = ros::Time::now() - begin;
00161 if (duration.toSec() > MAX_RUNTIME_SECONDS) {
00162 ROS_WARN("Iteration of vision loop took %f seconds (max is %f)", duration.toSec(), MAX_RUNTIME_SECONDS);
00163 }
00164 }
00165
00166 int main(int argc, char** argv)
00167 {
00168 ros::init (argc, argv, "turtle_default");
00169
00170
00171 ros::NodeHandle nh = ros::NodeHandle(ros::this_node::getName());
00172 std::string in, out, out_vel;
00173 nh.param<std::string>("in", in, "rndmwalk_in");
00174 nh.param<std::string>("out_vel", out_vel, "rndmwalk_out_vel");
00175 nh.param<double>("lin_speed", lin_speed, 0.3);
00176 nh.param<double>("ang_speed", ang_speed, 0.75);
00177 nh.param<double>("still_ang_speed", still_ang_speed, 2.0);
00178 nh.param<double>("cam_height", cam_height, 0.3);
00179 nh.param<double>("stop_distance", stop_distance, 0.8);
00180 nh.param<int>("stop_point_count", stop_point_count, 50);
00181
00182
00183 start_command = ros::Time::now().toSec() - 5.0;
00184
00185
00186 ros::NodeHandle nx;
00187 ros::Subscriber sub = nx.subscribe<PCLPointCloud>(in, 1, callback);
00188
00189
00190 ros::ServiceClient operation_mode_client;
00191 operation_mode_client = nx.serviceClient<turtlebot_node::SetTurtlebotMode>("/turtlebot_node/set_operation_mode");
00192 turtlebot_node::SetTurtlebotMode srvMsg;
00193 srvMsg.request.mode = 3;
00194 operation_mode_client.call(srvMsg);
00195
00196
00197 pubvel = nx.advertise<geometry_msgs::Twist> (out_vel, 1);
00198
00199
00200 base_normal[0] = 0.0;
00201 base_normal[1] = 1.0;
00202 base_normal[2] = 0.0;
00203 base_normal[3] = cam_height;
00204 last_normal[0] = base_normal[0];
00205 last_normal[1] = base_normal[1];
00206 last_normal[2] = base_normal[2];
00207 last_normal[3] = base_normal[3];
00208
00209
00210 ros::spin();
00211
00212 return (0);
00213 }
00214
00215
00216