29 #include <tf/transform_listener.h>
30 #include <tf/transform_broadcaster.h>
31 #include <sensor_msgs/LaserScan.h>
32 #include <sensor_msgs/Image.h>
33 #include <nav_msgs/Odometry.h>
34 #include <geometry_msgs/PoseArray.h>
35 #include <geometry_msgs/PoseWithCovarianceStamped.h>
36 #include <ros/package.h>
44 #include "cgr_localization/DisplayMsg.h"
45 #include "cgr_localization/LocalizationInterfaceSrv.h"
46 #include "cgr_localization/LocalizationMsg.h"
47 #include "configreader.h"
53 bool usePointCloud =
false;
55 int numParticles = 20;
60 float locUncertainty, angleUncertainty;
65 using namespace cgr_localization;
66 Publisher guiPublisher;
67 Publisher localizationPublisher;
68 Publisher filteredPointCloudPublisher;
69 ServiceServer localizationServer;
70 Publisher particlesPublisher;
71 tf::TransformBroadcaster *transformBroadcaster;
72 tf::TransformListener *transformListener;
74 sensor_msgs::PointCloud filteredPointCloudMsg;
80 vector<vector2f> pointCloud;
81 vector<vector2f> pointCloudNormals;
87 sensor_msgs::LaserScan lastLidarMsg;
88 sensor_msgs::Image lastDepthMsg;
89 geometry_msgs::PoseArray particlesMsg;
98 void lidarCallback(
const sensor_msgs::LaserScan& msg);
99 void depthCallback(
const sensor_msgs::Image& msg);
100 void publishLocation(
bool limitRate=
true);
102 bool localizationCallback(LocalizationInterfaceSrv::Request& req, LocalizationInterfaceSrv::Response& res)
105 if(debugLevel>0) printf(
"Setting location: %f %f %f\u00b0 on %s\n",V2COMP(loc),DEG(req.orientation),req.map.c_str());
106 localization->
setLocation(loc, req.orientation,req.map.c_str(),0.01,RAD(1.0));
112 guiMsg.lines_p1x.clear();
113 guiMsg.lines_p1y.clear();
114 guiMsg.lines_p2x.clear();
115 guiMsg.lines_p2y.clear();
116 guiMsg.points_x.clear();
117 guiMsg.points_y.clear();
118 guiMsg.lines_col.clear();
119 guiMsg.points_col.clear();
120 guiMsg.circles_x.clear();
121 guiMsg.circles_y.clear();
122 guiMsg.circles_col.clear();
124 guiMsg.windowSize = 1.0;
127 void drawPointCloud()
131 for(
int i=0; i<(int) pointCloud.size(); i++){
132 guiMsg.points_x.push_back(pointCloud[i].x);
133 guiMsg.points_y.push_back(pointCloud[i].y);
134 guiMsg.points_col.push_back(0xDE2352);
138 void publishLocation(
bool limitRate)
140 static double tLast = 0;
141 if(GetTimeSec()-tLast<0.03 && limitRate)
143 tLast = GetTimeSec();
146 msg.timeStamp = GetTimeSec();
149 msg.angle = curAngle;
152 localization->
getUncertainty(msg.angleUncertainty, msg.locationUncertainty);
156 msg.laserNumCorrespondences = laserEval.numCorrespondences;
157 msg.laserNumObservedPoints = laserEval.numObservedPoints;
158 msg.laserStage0Weights = laserEval.stage0Weights;
159 msg.laserStageRWeights = laserEval.stageRWeights;
160 msg.laserRunTime = laserEval.runTime;
161 msg.lastLaserRunTime = laserEval.lastRunTime;
162 msg.laserMeanSqError = laserEval.meanSqError;
164 msg.pointCloudNumCorrespondences = pointCloudEval.numCorrespondences;
165 msg.pointCloudNumObservedPoints = pointCloudEval.numObservedPoints;
166 msg.pointCloudStage0Weights = pointCloudEval.stage0Weights;
167 msg.pointCloudStageRWeights = pointCloudEval.stageRWeights;
168 msg.pointCloudRunTime = pointCloudEval.runTime;
169 msg.lastPointCloudRunTime = pointCloudEval.lastRunTime;
170 msg.pointCloudMeanSqError = pointCloudEval.meanSqError;
172 localizationPublisher.publish(msg);
175 vector<Particle2D> particles;
177 particlesMsg.poses.resize(particles.size());
178 geometry_msgs::Pose particle;
179 for(
unsigned int i=0; i<particles.size(); i++){
180 particle.position.x = particles[i].loc.x;
181 particle.position.y = particles[i].loc.y;
182 particle.position.z = 0;
183 particle.orientation.w = cos(0.5*particles[i].angle);
184 particle.orientation.x = 0;
185 particle.orientation.y = 0;
186 particle.orientation.z = sin(0.5*particles[i].angle);
187 particlesMsg.poses[i] = particle;
189 particlesPublisher.publish(particlesMsg);
193 tf::StampedTransform odomToBaseTf;
194 transformListener->lookupTransform(
"odom",
"base_footprint",ros::Time(0), odomToBaseTf);
197 float map_base_rot = curAngle;
199 vector2f odom_base_trans(odomToBaseTf.getOrigin().x(), odomToBaseTf.getOrigin().y());
200 float odom_base_rot = 2.0*atan2(odomToBaseTf.getRotation().z(), odomToBaseTf.getRotation().w());
202 vector2f base_odom_trans = -odom_base_trans.
rotate(-odom_base_rot);
203 float base_odom_rot = -odom_base_rot;
205 vector2f map_odom_trans = map_base_trans + base_odom_trans.
rotate(map_base_rot);
206 float map_odom_rot = angle_mod(map_base_rot + base_odom_rot);
208 tf::Transform mapToOdomTf;
209 mapToOdomTf.setOrigin(tf::Vector3(V2COMP(map_odom_trans), 0.0));
210 mapToOdomTf.setRotation(tf::Quaternion(tf::Vector3(0,0,1),map_odom_rot));
211 transformBroadcaster->sendTransform(tf::StampedTransform(mapToOdomTf, ros::Time::now(),
"map",
"odom"));
213 catch (tf::TransformException ex){
220 static double tLast = 0;
221 static double publishInterval = 0.016;
222 if(debugLevel<0 || GetTimeSec()-tLast<publishInterval)
224 tLast = GetTimeSec();
227 guiMsg.robotLocX = curLoc.x;
228 guiMsg.robotLocY = curLoc.y;
229 guiMsg.robotAngle = curAngle;
230 localization->
drawDisplay(guiMsg.lines_p1x, guiMsg.lines_p1y, guiMsg.lines_p2x, guiMsg.lines_p2y, guiMsg.lines_col, guiMsg.points_x, guiMsg.points_y, guiMsg.points_col, guiMsg.circles_x, guiMsg.circles_y, guiMsg.circles_col, 1.0);
232 guiPublisher.publish(guiMsg);
235 void LoadParameters()
238 ConfigReader config(ros::package::getPath(
"cgr_localization").append(
"/").c_str());
240 config.init(watch_files);
242 config.addFile(
"config/localization_parameters.cfg");
243 config.addFile(
"config/kinect_parameters.cfg");
245 if(!config.readFiles()){
246 printf(
"Failed to read config\n");
253 unsigned int maxDepthVal;
255 error = error || !c.getReal(
"f",kinectDepthCam.
f);
256 error = error || !c.getReal(
"fovH",kinectDepthCam.fovH);
257 error = error || !c.getReal(
"fovV",kinectDepthCam.fovV);
258 error = error || !c.getInt(
"width",kinectDepthCam.width);
259 error = error || !c.getInt(
"height",kinectDepthCam.height);
260 error = error || !c.getUInt(
"maxDepthVal",maxDepthVal);
264 float xRot, yRot, zRot;
265 error = error || !c.getVec3f(
"loc",kinectLoc);
266 error = error || !c.getReal(
"xRot",xRot);
267 error = error || !c.getReal(
"yRot",yRot);
268 error = error || !c.getReal(
"zRot",zRot);
269 kinectToRobotTransform.xyzRotationAndTransformation(xRot,yRot,zRot,kinectLoc);
272 printf(
"Error Loading Kinect Parameters!\n");
281 error = error || !c.getUInt(
"maxPoints",filterParams.maxPoints);
282 error = error || !c.getUInt(
"numSamples",filterParams.numSamples);
283 error = error || !c.getUInt(
"numLocalSamples",filterParams.numLocalSamples);
284 error = error || !c.getUInt(
"planeSize",filterParams.planeSize);
285 error = error || !c.getReal(
"maxError",filterParams.maxError);
286 error = error || !c.getReal(
"maxDepthDiff",filterParams.maxDepthDiff);
287 error = error || !c.getReal(
"minInlierFraction",filterParams.minInlierFraction);
288 error = error || !c.getReal(
"WorldPlaneSize",filterParams.WorldPlaneSize);
289 error = error || !c.getUInt(
"numRetries",filterParams.numRetries);
290 filterParams.runPolygonization =
false;
293 printf(
"Error Loading Plane Filtering Parameters!\n");
302 curMapName = string(c.getStr(
"mapName"));
303 error = error || curMapName.length()==0;
304 error = error || !c.getVec2f(
"loc",initialLoc);
305 error = error || !c.getReal(
"angle", initialAngle);
306 error = error || !c.getReal(
"locUncertainty", locUncertainty);
307 error = error || !c.getReal(
"angleUncertainty", angleUncertainty);
310 printf(
"Error Loading Initial Conditions!\n");
319 error = error || !c.getReal(
"Alpha1", motionParams.
Alpha1);
320 error = error || !c.getReal(
"Alpha2", motionParams.
Alpha2);
321 error = error || !c.getReal(
"Alpha3", motionParams.
Alpha3);
322 error = error || !c.getReal(
"kernelSize", motionParams.kernelSize);
326 printf(
"Error Loading Predict Parameters!\n");
336 error = error || !c.getReal(
"angleResolution", lidarParams.angleResolution);
337 error = error || !c.getInt(
"numRays", lidarParams.numRays);
338 error = error || !c.getReal(
"maxRange", lidarParams.maxRange);
339 error = error || !c.getReal(
"minRange", lidarParams.minRange);
343 float xRot, yRot, zRot;
344 error = error || !c.getVec2f<
vector2f>(
"laserToBaseTrans", laserToBaseTrans);
345 error = error || !c.getReal(
"xRot", xRot);
346 error = error || !c.getReal(
"yRot", yRot);
347 error = error || !c.getReal(
"zRot", zRot);
348 Matrix3f laserToBaseRot;
349 laserToBaseRot = AngleAxisf(xRot, Vector3f::UnitX()) * AngleAxisf(yRot, Vector3f::UnitY()) * AngleAxisf(zRot, Vector3f::UnitZ());
350 lidarParams.laserToBaseTrans = Vector2f(V2COMP(laserToBaseTrans));
351 lidarParams.laserToBaseRot = laserToBaseRot.block(0,0,2,2);
354 error = error || !c.getReal(
"logObstacleProb", lidarParams.logObstacleProb);
355 error = error || !c.getReal(
"logOutOfRangeProb", lidarParams.logOutOfRangeProb);
356 error = error || !c.getReal(
"logShortHitProb", lidarParams.logShortHitProb);
357 error = error || !c.getReal(
"correlationFactor", lidarParams.correlationFactor);
358 error = error || !c.getReal(
"lidarStdDev", lidarParams.lidarStdDev);
359 error = error || !c.getReal(
"attractorRange", lidarParams.attractorRange);
360 error = error || !c.getReal(
"kernelSize", lidarParams.kernelSize);
363 error = error || !c.getInt(
"minPoints", lidarParams.minPoints);
364 error = error || !c.getInt(
"numSteps", lidarParams.numSteps);
365 error = error || !c.getReal(
"etaAngle", lidarParams.etaAngle);
366 error = error || !c.getReal(
"etaLoc", lidarParams.etaLoc);
367 error = error || !c.getReal(
"maxAngleGradient", lidarParams.maxAngleGradient);
368 error = error || !c.getReal(
"maxLocGradient", lidarParams.maxLocGradient);
369 error = error || !c.getReal(
"minCosAngleError", lidarParams.minCosAngleError);
370 error = error || !c.getReal(
"correspondenceMargin", lidarParams.correspondenceMargin);
371 error = error || !c.getReal(
"minRefineFraction", lidarParams.minRefineFraction);
373 lidarParams.initialize();
376 printf(
"Error Loading Lidar Parameters!\n");
385 error = error || !c.getReal(
"logObstacleProb",
pointCloudParams.logObstacleProb);
386 error = error || !c.getReal(
"logShortHitProb",
pointCloudParams.logShortHitProb);
387 error = error || !c.getReal(
"logOutOfRangeProb",
pointCloudParams.logOutOfRangeProb);
388 error = error || !c.getReal(
"correlationFactor",
pointCloudParams.corelationFactor);
391 error = error || !c.getReal(
"attractorRange",
pointCloudParams.attractorRange);
395 error = error || !c.getReal(
"attractorRange",
pointCloudParams.attractorRange);
398 error = error || !c.getReal(
"maxAngleGradient",
pointCloudParams.maxAngleGradient);
399 error = error || !c.getReal(
"maxLocGradient",
pointCloudParams.maxLocGradient);
400 error = error || !c.getReal(
"minCosAngleError",
pointCloudParams.minCosAngleError);
405 error = error || !c.getReal(
"correspondenceMargin",
pointCloudParams.correspondenceMargin);
406 error = error || !c.getReal(
"minRefineFraction",
pointCloudParams.minRefineFraction);
409 printf(
"Error Loading Point Cloud Parameters!\n");
414 planeFilter.setParameters(&kinectDepthCam,filterParams);
418 lidarParams.laserScan = (
float*) malloc(lidarParams.numRays*
sizeof(
float));
420 filteredPointCloudMsg.header.seq = 0;
421 filteredPointCloudMsg.header.frame_id =
"base_footprint";
422 filteredPointCloudMsg.channels.clear();
427 void odometryCallback(
const nav_msgs::OdometryConstPtr &msg)
429 static float angle = 0;
431 static bool initialized=
false;
432 static double tLast = 0;
434 if(tLast>msg->header.stamp.toSec())
438 angle = tf::getYaw(msg->pose.pose.orientation);
439 loc =
vector2f(msg->pose.pose.position.x, msg->pose.pose.position.y);
444 float newAngle = tf::getYaw(msg->pose.pose.orientation);
445 vector2f newLoc(msg->pose.pose.position.x, msg->pose.pose.position.y);
447 vector2f d = (newLoc-loc).rotate(-angle);
450 double dtheta = angle_mod(newAngle-angle);
452 if((sq(dx)+sq(dy))>sq(0.4) || fabs(dtheta)>RAD(40)){
453 printf(
"Odometry out of bounds: x:%7.3f y:%7.3f a:%7.3f\u00b0\n",dx, dy, DEG(dtheta));
459 if(debugLevel>0) printf(
"Odometry t:%f x:%7.3f y:%7.3f a:%7.3f\u00b0\n",msg->header.stamp.toSec(), dx, dy, DEG(dtheta));
461 localization->
predict(dx, dy, dtheta, motionParams);
467 void lidarCallback(
const sensor_msgs::LaserScan &msg)
471 printf(
"LIDAR n:%d t:%f noLidar:%d\n",(
int) msg.ranges.size(), msg.scan_time, noLidar?1:0);
474 tf::StampedTransform baseLinkToLaser;
476 transformListener->lookupTransform(
"base_footprint", msg.header.frame_id, ros::Time(0), baseLinkToLaser);
478 catch(tf::TransformException ex){
479 ROS_ERROR(
"%s",ex.what());
481 tf::Vector3 translationTf = baseLinkToLaser.getOrigin();
482 tf::Quaternion rotationTf = baseLinkToLaser.getRotation();
484 Quaternionf rotQuat3D(rotationTf.w(), rotationTf.x(), rotationTf.y(), rotationTf.z());
485 Matrix3f rot3D(rotQuat3D);
486 Vector3f trans3D(translationTf.x(), translationTf.y(),translationTf.z());
488 trans3D = rot3D*trans3D;
489 lidarParams.laserToBaseRot = rot3D.topLeftCorner(2,2);
490 lidarParams.laserToBaseTrans = trans3D.topLeftCorner(2,1);
492 bool newLaser = lidarParams.minRange != msg.range_min ||
493 lidarParams.maxRange != msg.range_max ||
494 lidarParams.minAngle != msg.angle_min ||
495 lidarParams.maxAngle != msg.angle_max ||
496 lidarParams.angleResolution != msg.angle_increment ||
497 lidarParams.numRays != int(msg.ranges.size());
499 lidarParams.minRange = msg.range_min;
500 lidarParams.maxRange = msg.range_max;
501 lidarParams.minAngle = msg.angle_min;
502 lidarParams.maxAngle = msg.angle_max;
503 lidarParams.angleResolution = msg.angle_increment;
504 lidarParams.numRays = int(msg.ranges.size());
505 lidarParams.initialize();
508 if(
int(msg.ranges.size()) != lidarParams.numRays){
509 TerminalWarning(
"Incorrect number of Laser Scan rays!");
510 printf(
"received: %d\n",
int(msg.ranges.size()));
513 for(
int i=0; i<(int)msg.ranges.size(); i++)
514 lidarParams.laserScan[i] = msg.ranges[i];
519 localization->
updateLidar(lidarParams, motionParams);
520 localization->
resample(VectorLocalization2D::LowVarianceResampling);
526 void depthCallback(
const sensor_msgs::Image &msg)
530 printf(
"Depth Message t:%f\n", msg.header.stamp.toSec());
532 const uint8_t* ptrSrc = msg.data.data();
533 uint16_t depth[640*480];
534 memcpy(depth, ptrSrc, 640*480*(
sizeof(uint16_t)));
539 tf::StampedTransform baseLinkToKinect;
541 transformListener->lookupTransform(
"base_footprint", msg.header.frame_id, ros::Time(0), baseLinkToKinect);
543 catch(tf::TransformException ex){
544 ROS_ERROR(
"%s",ex.what());
546 tf::Vector3 translationTf = baseLinkToKinect.getOrigin();
547 tf::Quaternion rotationTf = baseLinkToKinect.getRotation();
548 Quaternionf rotQuat3D(rotationTf.w(), rotationTf.x(), rotationTf.y(), rotationTf.z());
549 Matrix3f rotMatrix(rotQuat3D);
550 kinectToRobotTransform.m11 = rotMatrix(0,0);
551 kinectToRobotTransform.m12 = rotMatrix(0,1);
552 kinectToRobotTransform.m13 = rotMatrix(0,2);
553 kinectToRobotTransform.m14 = translationTf.x();
554 kinectToRobotTransform.m21 = rotMatrix(1,0);
555 kinectToRobotTransform.m22 = rotMatrix(1,1);
556 kinectToRobotTransform.m23 = rotMatrix(1,2);
557 kinectToRobotTransform.m24 = translationTf.y();
558 kinectToRobotTransform.m31 = rotMatrix(2,0);
559 kinectToRobotTransform.m32 = rotMatrix(2,1);
560 kinectToRobotTransform.m33 = rotMatrix(2,2);
561 kinectToRobotTransform.m34 = translationTf.z();
562 kinectToRobotTransform.m41 = 0;
563 kinectToRobotTransform.m42 = 0;
564 kinectToRobotTransform.m43 = 0;
565 kinectToRobotTransform.m44 = 1;
568 vector<vector3f> filteredPointCloud;
569 vector<vector3f> pointCloudNormals;
570 vector<vector3f> outlierCloud;
571 vector<vector2i> pixelLocs;
572 vector<PlanePolygon> planePolygons;
578 for(
unsigned int i=0; i<filteredPointCloud.size(); i++){
579 filteredPointCloud[i] = filteredPointCloud[i].transform(kinectToRobotTransform);
580 pointCloudNormals[i] = pointCloudNormals[i].transform(kinectToRobotTransform);
585 filteredPointCloudMsg.points.clear();
586 filteredPointCloudMsg.header.stamp = ros::Time::now();
588 vector<geometry_msgs::Point32>* points = &(filteredPointCloudMsg.points);
589 geometry_msgs::Point32 p;
590 for(
int i=0; i<(int)filteredPointCloud.size(); i++){
591 p.x = filteredPointCloud[i].x;
592 p.y = filteredPointCloud[i].y;
593 p.z = filteredPointCloud[i].z;
594 points->push_back(p);
596 filteredPointCloudPublisher.publish(filteredPointCloudMsg);
601 vector<vector2f> pointCloud2D, pointCloudNormals2D;
603 for(
unsigned int i=0; i<filteredPointCloud.size(); i++){
604 if(fabs(pointCloudNormals[i].z)>sin(RAD(30.0)))
607 vector2f curNormal(V2COMP(pointCloudNormals[i]));
608 vector2f curPoint(V2COMP(filteredPointCloud[i]));
609 curNormal.normalize();
610 pointCloudNormals2D.push_back(curNormal);
611 pointCloud2D.push_back(curPoint);
616 localization->
resample(VectorLocalization2D::LowVarianceResampling);
621 void initialPoseCallback(
const geometry_msgs::PoseWithCovarianceStamped &msg)
623 float angle = 2.0*asin(msg.pose.pose.orientation.z);
624 vector2f loc(V2COMP(msg.pose.pose.position));
625 printf(
"Initializing CGR localization at %.3f,%.3f, %.2f\u00b0\n",V2COMP(loc), DEG(angle));
627 localization->
initialize(numParticles,curMapName.c_str(), loc, angle,0.01,RAD(1.0));
630 int main(
int argc,
char** argv)
636 static struct poptOption options[] = {
637 {
"num-particles",
'n', POPT_ARG_INT, &numParticles, 0,
"Number of Particles",
"NUM"},
638 {
"debug",
'd', POPT_ARG_INT, &debugLevel, 0,
"Debug Level",
"NUM"},
639 {
"start-x",
'x', POPT_ARG_DOUBLE, &initialLoc.x, 0,
"Starting X location",
"NUM"},
640 {
"start-y",
'y', POPT_ARG_DOUBLE, &initialLoc.y, 0,
"Starting Y location",
"NUM"},
641 {
"start-angle",
'a', POPT_ARG_DOUBLE, &initialAngle, 0,
"Starting Angle",
"NUM"},
642 {
"use-point-cloud",
'p', POPT_ARG_NONE, &usePointCloud, 0,
"Use Point Cloud",
"NONE"},
643 {
"no-lidar",
'l', POPT_ARG_NONE, &noLidar, 0,
"No LIDAR Observations",
"NONE"},
644 {
"Alpha1-param",
'u', POPT_ARG_DOUBLE, &motionParams.
Alpha1, 0,
"Alpha1 parameter",
"NUM"},
645 {
"Alpha2-param",
'v', POPT_ARG_DOUBLE, &motionParams.
Alpha2, 0,
"Alpha2 parameter",
"NUM"},
646 {
"Alpha3-param",
'w', POPT_ARG_DOUBLE, &motionParams.
Alpha3, 0,
"Alpha3 parameter",
"NUM"},
649 { NULL, 0, 0, NULL, 0, NULL, NULL }
652 POpt popt(NULL,argc,(
const char**)argv,options,0);
654 while((c = popt.getNextOpt()) >= 0){
658 ColourTerminal(TerminalUtils::TERMINAL_COL_WHITE,TerminalUtils::TERMINAL_COL_BLACK,TerminalUtils::TERMINAL_ATTR_BRIGHT);
659 printf(
"\nVector Localization\n\n");
663 printf(
"NumParticles : %d\n",numParticles);
664 printf(
"Alpha1 : %f\n",motionParams.
Alpha1);
665 printf(
"Alpha2 : %f\n",motionParams.
Alpha2);
666 printf(
"Alpha3 : %f\n",motionParams.
Alpha3);
667 printf(
"UsePointCloud : %d\n",usePointCloud?1:0);
668 printf(
"UseLIDAR : %d\n",noLidar?0:1);
669 printf(
"Visualizations : %d\n",debugLevel>=0?1:0);
672 double seed = floor(fmod(GetTimeSec()*1000000.0,1000000.0));
673 if(debugLevel>-1) printf(
"Seeding with %d\n",(
unsigned int)seed);
677 string mapsFolder(ros::package::getPath(
"cgr_localization").append(
"/maps/"));
682 localization->
initialize(numParticles,curMapName.c_str(),initialLoc,initialAngle,locUncertainty,angleUncertainty);
685 InitHandleStop(&run);
686 ros::init(argc, argv,
"CGR_Localization");
688 guiPublisher = n.advertise<DisplayMsg>(
"localization_gui",1,
true);
689 localizationPublisher = n.advertise<LocalizationMsg>(
"localization",1,
true);
690 particlesPublisher = n.advertise<geometry_msgs::PoseArray>(
"particlecloud",1,
false);
693 localizationServer = n.advertiseService(
"localization_interface", &localizationCallback);
696 ros::Subscriber odometrySubscriber = n.subscribe(
"odom", 20, odometryCallback);
697 ros::Subscriber lidarSubscriber = n.subscribe(
"scan", 5, lidarCallback);
698 ros::Subscriber kinectSubscriber = n.subscribe(
"kinect_depth", 1, depthCallback);
699 ros::Subscriber initialPoseSubscriber = n.subscribe(
"initialpose",1,initialPoseCallback);
700 transformListener =
new tf::TransformListener(ros::Duration(10.0));
701 transformBroadcaster =
new tf::TransformBroadcaster();
703 filteredPointCloudPublisher = n.advertise<sensor_msgs::PointCloud>(
"Cobot/Kinect/FilteredPointCloud", 1);
705 while(ros::ok() && run){
712 if(debugLevel>=0) printf(
"closing.\n");
void getParticles(vector< Particle2D > &_particles)
Returns current particles.
Subroutines to spice up stdout.
void refinePointCloud(const vector< vector2f > &pointCloud, const vector< vector2f > &pointNormals, const VectorLocalization2D::PointCloudParams &pointCloudParams)
Refine proposal distribution based on Point Cloud observations.
C++ Implementation: Particle, VectorLocalization.
C++ Interfaces: VectorMap, LineSection.
void updatePointCloud(vector< vector2f > &pointCloud, vector< vector2f > &pointNormals, const VectorLocalization2D::MotionModelParams &motionParams, const VectorLocalization2D::PointCloudParams &pointCloudParams)
Update distribution based on Point Cloud observations.
void initialize(int _numParticles, const char *mapName, vector2f loc, float angle, float locationUncertainty=0.0, float angleUncertainty=0.0)
Initialise arrays, and sets initial location to.
Parameters for plane filtering.
VectorLocalization2D::PointCloudParams pointCloudParams
FSPF point cloud.
float Alpha1
Alpha1 = Error in angle per delta in angle.
void refineLidar(const VectorLocalization2D::LidarParams &lidarParams)
Refine proposal distribution based on LIDAR observations.
void drawDisplay(vector< float > &lines_p1x, vector< float > &lines_p1y, vector< float > &lines_p2x, vector< float > &lines_p2y, vector< uint32_t > &lines_color, vector< float > &points_x, vector< float > &points_y, vector< uint32_t > &points_color, vector< float > &circles_x, vector< float > &circles_y, vector< uint32_t > &circles_color, float scale=1.0)
Compile lists of drawing primitives that can be visualized for debugging purposes.
void setLocation(vector2f loc, float angle, const char *map, float locationUncertainty, float angleUncertainty)
Set pose with specified uncertainty.
void predict(float dx, float dy, float dtheta, const VectorLocalization2D::MotionModelParams &motionParams)
Predict step of the particle filter. Samples from the motion model.
void computeLocation(vector2f &loc, float &angle)
Compute the maximum likelihood location based on particle spread.
float Alpha2
Alpha2 = Error in angle per delta in translation.
void updateLidar(const VectorLocalization2D::LidarParams &lidarParams, const VectorLocalization2D::MotionModelParams &motionParams)
Update distribution based on LIDAR observations.
void resample(Resample type=LowVarianceResampling)
Resample distribution.
void getEvalValues(EvalValues &_laserEval, EvalValues &_pointCloudEval)
Return evaluation values.
void GenerateFilteredPointCloud(void *depthImage, vector< vector3f > &filteredPointCloud, vector< vector2i > &pixelLocs, vector< vector3f > &pointCloudNormals, vector< vector3f > &outlierCloud, vector< PlanePolygon > &polygons)
Accepts a depth image, returns filtered point cloud + normals, outliers, and all sampled points...
const char * getCurrentMapName()
Returns the current map name.
uint16_t maxDepthVal
Maximum valid depth value.
vector2d< num > rotate(const double a) const MustUseResult
return vector rotated by angle a
Raw Kinect Depth Camera to process raw depth images from libfreenect.
Interface to PlaneFiltering class, to perform plane filtering of 3D point clouds from depth images...
void getUncertainty(float &_angleUnc, float &_locUnc)
Return angle and location uncertainties.
float Alpha3
Alpha3 = Error in translation per delta in translation.