diff --git a/ar_track_alvar/launch/pr2_bundle_no_kinect.launch b/ar_track_alvar/launch/pr2_bundle_no_kinect.launch
index c7892dd..a7f4950 100755
--- a/ar_track_alvar/launch/pr2_bundle_no_kinect.launch
+++ b/ar_track_alvar/launch/pr2_bundle_no_kinect.launch
@@ -9,5 +9,14 @@
-
+
+
+
+
+
+
+
+
+
+
diff --git a/ar_track_alvar/nodes/FindMarkerBundles.cpp b/ar_track_alvar/nodes/FindMarkerBundles.cpp
index e7f83e0..c63a8cb 100644
--- a/ar_track_alvar/nodes/FindMarkerBundles.cpp
+++ b/ar_track_alvar/nodes/FindMarkerBundles.cpp
@@ -33,39 +33,32 @@
author: Scott Niekum
*/
-#include "ar_track_alvar/CvTestbed.h"
#include "ar_track_alvar/MarkerDetector.h"
#include "ar_track_alvar/MultiMarkerBundle.h"
#include "ar_track_alvar/MultiMarkerInitializer.h"
-#include "ar_track_alvar/Shared.h"
#include
#include
#include
#include
#include
+#include
#include
#include
#include
-#include
-#include
#include
#include
#include
-#include
-#include
-#include
-#include
#include
-#include
-#include
-#include
#include
#include
+#include
#include
#include
+#include
+#include
#define MAIN_MARKER 1
@@ -93,42 +86,47 @@ ar_track_alvar_msgs::AlvarMarkers arPoseMarkers_;
tf::TransformListener *tf_listener;
tf::TransformBroadcaster *tf_broadcaster;
MarkerDetector marker_detector;
-MultiMarkerBundle **multi_marker_bundles=NULL;
+MultiMarkerBundle **multi_marker_bundles=nullptr;
Pose *bundlePoses;
int *master_id;
int *bundles_seen;
bool *master_visible;
-std::vector *bundle_indices;
+std::vector *bundle_indices;
bool init = true;
ata::MedianFilter **med_filts;
int med_filt_size;
+bool enable_switched = false;
+bool enabled = true;
double marker_size;
double max_new_marker_error;
double max_track_error;
-std::string cam_image_topic;
-std::string cam_info_topic;
+std::string cam_image_topic;
+std::string cam_info_topic;
std::string output_frame;
-int n_bundles = 0;
+double max_frequency = 8.0; // default maximum frequency
+int marker_resolution = 5; // default marker resolution
+int marker_margin = 2; // default marker margin
+int n_bundles = 0;
//Debugging utility function
-void draw3dPoints(ARCloud::Ptr cloud, string frame, int color, int id, double rad)
+void draw3dPoints(const ARCloud::Ptr& cloud, const string &frame, int color, int id, double rad)
{
visualization_msgs::Marker rvizMarker;
rvizMarker.header.frame_id = frame;
- rvizMarker.header.stamp = ros::Time::now();
+ rvizMarker.header.stamp = ros::Time::now();
rvizMarker.id = id;
rvizMarker.ns = "3dpts";
-
+
rvizMarker.scale.x = rad;
rvizMarker.scale.y = rad;
rvizMarker.scale.z = rad;
-
+
rvizMarker.type = visualization_msgs::Marker::SPHERE_LIST;
rvizMarker.action = visualization_msgs::Marker::ADD;
-
+
if(color==1){
rvizMarker.color.r = 0.0f;
rvizMarker.color.g = 1.0f;
@@ -147,38 +145,38 @@ void draw3dPoints(ARCloud::Ptr cloud, string frame, int color, int id, double ra
rvizMarker.color.b = 0.0f;
rvizMarker.color.a = 1.0;
}
-
+
gm::Point p;
- for(int i=0; ipoints.size(); i++){
- p.x = cloud->points[i].x;
- p.y = cloud->points[i].y;
- p.z = cloud->points[i].z;
+ for(auto & point : cloud->points){
+ p.x = point.x;
+ p.y = point.y;
+ p.z = point.z;
rvizMarker.points.push_back(p);
}
-
+
rvizMarker.lifetime = ros::Duration (1.0);
rvizMarkerPub2_.publish (rvizMarker);
}
-void drawArrow(gm::Point start, tf::Matrix3x3 mat, string frame, int color, int id)
+void drawArrow(const gm::Point &start, const tf::Matrix3x3 &mat, const string &frame, int color, int id)
{
visualization_msgs::Marker rvizMarker;
-
+
rvizMarker.header.frame_id = frame;
- rvizMarker.header.stamp = ros::Time::now();
+ rvizMarker.header.stamp = ros::Time::now();
rvizMarker.id = id;
rvizMarker.ns = "arrow";
-
+
rvizMarker.scale.x = 0.01;
rvizMarker.scale.y = 0.01;
rvizMarker.scale.z = 0.1;
-
+
rvizMarker.type = visualization_msgs::Marker::ARROW;
rvizMarker.action = visualization_msgs::Marker::ADD;
-
+
for(int i=0; i<3; i++){
- rvizMarker.points.clear();
+ rvizMarker.points.clear();
rvizMarker.points.push_back(start);
gm::Point end;
end.x = start.x + mat[0][i];
@@ -214,7 +212,7 @@ void drawArrow(gm::Point start, tf::Matrix3x3 mat, string frame, int color, int
// Infer the master tag corner positons from the other observed tags
-// Also does some of the bookkeeping for tracking that MultiMarker::_GetPose does
+// Also does some of the bookkeeping for tracking that MultiMarker::_GetPose does
int InferCorners(const ARCloud &cloud, MultiMarkerBundle &master, ARCloud &bund_corners){
bund_corners.clear();
bund_corners.resize(4);
@@ -225,19 +223,18 @@ int InferCorners(const ARCloud &cloud, MultiMarkerBundle &master, ARCloud &bund_
}
// Reset the marker_status to 1 for all markers in point_cloud for tracking purposes
- for (size_t i=0; i 0) master.marker_status[i]=1;
+ for (int & marker_status : master.marker_status) {
+ if (marker_status > 0) marker_status=1;
}
int n_est = 0;
// For every detected marker
- for (size_t i=0; isize(); i++)
+ for (auto & i : *marker_detector.markers)
{
- const Marker* marker = &((*marker_detector.markers)[i]);
- int id = marker->GetId();
+ const Marker* marker = &i;
+ int id = static_cast(marker->GetId());
int index = master.get_id_index(id);
- int mast_id = master.master_id;
if (index < 0) continue;
// But only if we have corresponding points in the pointcloud
@@ -256,15 +253,15 @@ int InferCorners(const ARCloud &cloud, MultiMarkerBundle &master, ARCloud &bund_
tf::Vector3 corner_coord = master.rel_corners[index][j];
gm::PointStamped p, output_p;
p.header.frame_id = marker_frame;
- p.point.x = corner_coord.y()/100.0;
+ p.point.x = corner_coord.y()/100.0;
p.point.y = -corner_coord.x()/100.0;
p.point.z = corner_coord.z()/100.0;
-
+
try{
tf_listener->waitForTransform(cloud.header.frame_id, marker_frame, ros::Time(0), ros::Duration(0.1));
- tf_listener->transformPoint(cloud.header.frame_id, p, output_p);
+ tf_listener->transformPoint(cloud.header.frame_id, p, output_p);
}
- catch (tf::TransformException ex){
+ catch (const tf::TransformException &ex){
ROS_ERROR("ERROR InferCorners: %s",ex.what());
return -1;
}
@@ -276,13 +273,13 @@ int InferCorners(const ARCloud &cloud, MultiMarkerBundle &master, ARCloud &bund_
master.marker_status[index] = 2; // Used for tracking
}
}
-
+
//Divide to take the average of the summed estimates
if(n_est > 0){
for(int i=0; i<4; i++){
- bund_corners[i].x /= n_est;
- bund_corners[i].y /= n_est;
- bund_corners[i].z /= n_est;
+ bund_corners[i].x /= static_cast(n_est);
+ bund_corners[i].y /= static_cast(n_est);
+ bund_corners[i].z /= static_cast(n_est);
}
}
@@ -290,7 +287,7 @@ int InferCorners(const ARCloud &cloud, MultiMarkerBundle &master, ARCloud &bund_
}
-int PlaneFitPoseImprovement(int id, const ARCloud &corners_3D, ARCloud::Ptr selected_points, const ARCloud &cloud, Pose &p){
+int PlaneFitPoseImprovement(int id, const ARCloud &corners_3D, const ARCloud::Ptr& selected_points, const ARCloud &cloud, Pose &p){
ata::PlaneFitResult res = ata::fitPlane(selected_points);
gm::PoseStamped pose;
@@ -299,13 +296,13 @@ int PlaneFitPoseImprovement(int id, const ARCloud &corners_3D, ARCloud::Ptr sele
pose.pose.position = ata::centroid(*res.inliers);
draw3dPoints(selected_points, cloud.header.frame_id, 1, id, 0.005);
-
- //Get 2 points that point forward in marker x direction
+
+ //Get 2 points that point forward in marker x direction
int i1,i2;
- if(isnan(corners_3D[0].x) || isnan(corners_3D[0].y) || isnan(corners_3D[0].z) ||
+ if(isnan(corners_3D[0].x) || isnan(corners_3D[0].y) || isnan(corners_3D[0].z) ||
isnan(corners_3D[3].x) || isnan(corners_3D[3].y) || isnan(corners_3D[3].z))
{
- if(isnan(corners_3D[1].x) || isnan(corners_3D[1].y) || isnan(corners_3D[1].z) ||
+ if(isnan(corners_3D[1].x) || isnan(corners_3D[1].y) || isnan(corners_3D[1].z) ||
isnan(corners_3D[2].x) || isnan(corners_3D[2].y) || isnan(corners_3D[2].z))
{
return -1;
@@ -313,41 +310,41 @@ int PlaneFitPoseImprovement(int id, const ARCloud &corners_3D, ARCloud::Ptr sele
else{
i1 = 1;
i2 = 2;
- }
+ }
}
else{
i1 = 0;
i2 = 3;
}
- //Get 2 points the point forward in marker y direction
+ //Get 2 points the point forward in marker y direction
int i3,i4;
- if(isnan(corners_3D[0].x) || isnan(corners_3D[0].y) || isnan(corners_3D[0].z) ||
+ if(isnan(corners_3D[0].x) || isnan(corners_3D[0].y) || isnan(corners_3D[0].z) ||
isnan(corners_3D[1].x) || isnan(corners_3D[1].y) || isnan(corners_3D[1].z))
- {
- if(isnan(corners_3D[3].x) || isnan(corners_3D[3].y) || isnan(corners_3D[3].z) ||
+ {
+ if(isnan(corners_3D[3].x) || isnan(corners_3D[3].y) || isnan(corners_3D[3].z) ||
isnan(corners_3D[2].x) || isnan(corners_3D[2].y) || isnan(corners_3D[2].z))
- {
+ {
return -1;
}
else{
i3 = 2;
i4 = 3;
- }
+ }
}
else{
i3 = 1;
i4 = 0;
}
-
+
ARCloud::Ptr orient_points(new ARCloud());
orient_points->points.push_back(corners_3D[i1]);
draw3dPoints(orient_points, cloud.header.frame_id, 3, id+1000, 0.008);
-
+
orient_points->clear();
orient_points->points.push_back(corners_3D[i2]);
draw3dPoints(orient_points, cloud.header.frame_id, 2, id+2000, 0.008);
-
+
int succ;
succ = ata::extractOrientation(res.coeffs, corners_3D[i1], corners_3D[i2], corners_3D[i3], corners_3D[i4], pose.pose.orientation);
if(succ < 0) return -1;
@@ -364,7 +361,7 @@ int PlaneFitPoseImprovement(int id, const ARCloud &corners_3D, ARCloud::Ptr sele
p.quaternion[1] = pose.pose.orientation.x;
p.quaternion[2] = pose.pose.orientation.y;
p.quaternion[3] = pose.pose.orientation.z;
- p.quaternion[0] = pose.pose.orientation.w;
+ p.quaternion[0] = pose.pose.orientation.w;
return 0;
}
@@ -378,19 +375,19 @@ void GetMultiMarkerPoses(IplImage *image, ARCloud &cloud) {
master_visible[i] = false;
bundles_seen[i] = 0;
}
-
+
//Detect and track the markers
if (marker_detector.Detect(image, cam, true, false, max_new_marker_error,
- max_track_error, CVSEQ, true))
+ max_track_error, CVSEQ, true))
{
//printf("\n--------------------------\n\n");
for (size_t i=0; isize(); i++)
{
vector > pixels;
Marker *m = &((*marker_detector.markers)[i]);
- int id = m->GetId();
+ int id = static_cast(m->GetId());
//cout << "******* ID: " << id << endl;
-
+
//Get the 3D points of the outer corners
/*
PointDouble corner0 = m->marker_corners_img[0];
@@ -402,22 +399,22 @@ void GetMultiMarkerPoses(IplImage *image, ARCloud &cloud) {
m->ros_corners_3D[2] = cloud(corner2.x, corner2.y);
m->ros_corners_3D[3] = cloud(corner3.x, corner3.y);
*/
-
+
//Get the 3D inner corner points - more stable than outer corners that can "fall off" object
int resol = m->GetRes();
int ori = m->ros_orientation;
-
+
PointDouble pt1, pt2, pt3, pt4;
pt4 = m->ros_marker_points_img[0];
pt3 = m->ros_marker_points_img[resol-1];
pt1 = m->ros_marker_points_img[(resol*resol)-resol];
pt2 = m->ros_marker_points_img[(resol*resol)-1];
-
+
m->ros_corners_3D[0] = cloud(pt1.x, pt1.y);
m->ros_corners_3D[1] = cloud(pt2.x, pt2.y);
m->ros_corners_3D[2] = cloud(pt3.x, pt3.y);
m->ros_corners_3D[3] = cloud(pt4.x, pt4.y);
-
+
if(ori >= 0 && ori < 4){
if(ori != 0){
std::rotate(m->ros_corners_3D.begin(), m->ros_corners_3D.begin() + ori, m->ros_corners_3D.end());
@@ -430,14 +427,14 @@ void GetMultiMarkerPoses(IplImage *image, ARCloud &cloud) {
int master_ind = -1;
for(int j=0; jros_marker_points_img)
- pixels.push_back(cv::Point(p.x, p.y));
+ pixels.emplace_back(p.x, p.y);
ARCloud::Ptr selected_points = ata::filterCloud(cloud, pixels);
//Use the kinect data to find a plane and pose for the marker
int ret = PlaneFitPoseImprovement(i, m->ros_corners_3D, selected_points, cloud, m->pose);
-
+
//If the plane fit fails...
if(ret < 0){
//Mark this tag as invalid
@@ -463,14 +460,14 @@ void GetMultiMarkerPoses(IplImage *image, ARCloud &cloud) {
master_visible[master_ind] = false;
//decrement the number of markers seen in this bundle
bundles_seen[bundle_ind] -= 1;
-
+
}
else
m->valid = true;
- }
+ }
//For each master tag, infer the 3D position of its corners from other visible tags
- //Then, do a plane fit to those new corners
+ //Then, do a plane fit to those new corners
ARCloud inferred_corners;
for(int i=0; i 0){
@@ -483,27 +480,27 @@ void GetMultiMarkerPoses(IplImage *image, ARCloud &cloud) {
//If master is visible, use it directly instead of inferring pose
//else{
// for (size_t j=0; jsize(); j++){
- // Marker *m = &((*marker_detector.markers)[j]);
+ // Marker *m = &((*marker_detector.markers)[j]);
// if(m->GetId() == master_id[i])
// bundlePoses[i] = m->pose;
- // }
+ // }
//}
Pose ret_pose;
if(med_filt_size > 0){
med_filts[i]->addPose(bundlePoses[i]);
med_filts[i]->getMedian(ret_pose);
bundlePoses[i] = ret_pose;
- }
- }
+ }
+ }
}
}
}
-// Given the pose of a marker, builds the appropriate ROS messages for later publishing
-void makeMarkerMsgs(int type, int id, Pose &p, sensor_msgs::ImageConstPtr image_msg, tf::StampedTransform &CamToOutput, visualization_msgs::Marker *rvizMarker, ar_track_alvar_msgs::AlvarMarker *ar_pose_marker, int confidence){
+// Given the pose of a marker, builds the appropriate ROS messages for later publishing
+void makeMarkerMsgs(int type, int id, Pose &p, const sensor_msgs::ImageConstPtr& image_msg, tf::StampedTransform &CamToOutput, visualization_msgs::Marker *rvizMarker, ar_track_alvar_msgs::AlvarMarker *ar_pose_marker, int confidence){
double px,py,pz,qx,qy,qz,qw;
-
+
px = p.translation[0]/100.0;
py = p.translation[1]/100.0;
pz = p.translation[2]/100.0;
@@ -527,7 +524,7 @@ void makeMarkerMsgs(int type, int id, Pose &p, sensor_msgs::ImageConstPtr image_
out << id;
std::string id_string = out.str();
markerFrame += id_string;
- tf::StampedTransform camToMarker (t, image_msg->header.stamp, image_msg->header.frame_id, markerFrame.c_str());
+ tf::StampedTransform camToMarker (t, image_msg->header.stamp, image_msg->header.frame_id, markerFrame);
tf_broadcaster->sendTransform(camToMarker);
//Create the rviz visualization message
@@ -571,7 +568,7 @@ void makeMarkerMsgs(int type, int id, Pose &p, sensor_msgs::ImageConstPtr image_
rvizMarker->lifetime = ros::Duration (0.1);
- // Only publish the pose of the master tag in each bundle, since that's all we really care about aside from visualization
+ // Only publish the pose of the master tag in each bundle, since that's all we really care about aside from visualization
if(type==MAIN_MARKER){
//Take the pose of the tag in the camera frame and convert to the output frame (usually torso_lift_link for the PR2)
tf::Transform tagPoseOutput = CamToOutput * markerPose;
@@ -583,8 +580,6 @@ void makeMarkerMsgs(int type, int id, Pose &p, sensor_msgs::ImageConstPtr image_
ar_pose_marker->id = id;
ar_pose_marker->confidence = confidence;
}
- else
- ar_pose_marker = NULL;
}
@@ -603,7 +598,7 @@ void getPointCloudCallback (const sensor_msgs::PointCloud2ConstPtr &msg)
tf_listener->waitForTransform(output_frame, msg->header.frame_id, msg->header.stamp, ros::Duration(1.0));
tf_listener->lookupTransform(output_frame, msg->header.frame_id, msg->header.stamp, CamToOutput);
}
- catch (tf::TransformException ex){
+ catch (const tf::TransformException &ex){
ROS_ERROR("%s",ex.what());
}
@@ -612,7 +607,7 @@ void getPointCloudCallback (const sensor_msgs::PointCloud2ConstPtr &msg)
ar_track_alvar_msgs::AlvarMarker ar_pose_marker;
arPoseMarkers_.markers.clear ();
- //Convert cloud to PCL
+ //Convert cloud to PCL
ARCloud cloud;
pcl::fromROSMsg(*msg, cloud);
@@ -620,7 +615,7 @@ void getPointCloudCallback (const sensor_msgs::PointCloud2ConstPtr &msg)
pcl::toROSMsg (*msg, *image_msg);
image_msg->header.stamp = msg->header.stamp;
image_msg->header.frame_id = msg->header.frame_id;
-
+
//Convert the image
cv_ptr_ = cv_bridge::toCvCopy(image_msg, sensor_msgs::image_encodings::BGR8);
@@ -632,9 +627,9 @@ void getPointCloudCallback (const sensor_msgs::PointCloud2ConstPtr &msg)
IplImage ipl_image = cv_ptr_->image;
GetMultiMarkerPoses(&ipl_image, cloud);
- for (size_t i=0; isize(); i++)
+ for (auto & marker : *marker_detector.markers)
{
- int id = (*(marker_detector.markers))[i].GetId();
+ int id = static_cast(marker.GetId());
// Draw if id is valid
if(id >= 0){
@@ -644,14 +639,14 @@ void getPointCloudCallback (const sensor_msgs::PointCloud2ConstPtr &msg)
for(int j=0; j eig_quat(eig_m);
-
+
// Translate back to bullet
tfScalar ex = eig_quat.x();
tfScalar ey = eig_quat.y();
@@ -711,15 +706,15 @@ int makeMasterTransform (const CvPoint3D64f& p0, const CvPoint3D64f& p1,
tfScalar ew = eig_quat.w();
tf::Quaternion quat(ex,ey,ez,ew);
quat = quat.normalized();
-
+
double qx = (q0.x() + q1.x() + q2.x() + q3.x()) / 4.0;
double qy = (q0.y() + q1.y() + q2.y() + q3.y()) / 4.0;
double qz = (q0.z() + q1.z() + q2.z() + q3.z()) / 4.0;
tf::Vector3 origin (qx,qy,qz);
-
+
tf::Transform tform (quat, origin); //transform from master to marker
retT = tform;
-
+
return 0;
}
@@ -730,96 +725,161 @@ int calcAndSaveMasterCoords(MultiMarkerBundle &master)
{
int mast_id = master.master_id;
std::vector rel_corner_coords;
-
+
//Go through all the markers associated with this bundle
for (size_t i=0; idata;
+ enabled = msg->data;
+}
int main(int argc, char *argv[])
{
- ros::init (argc, argv, "marker_detect");
- ros::NodeHandle n;
-
- if(argc < 9){
- std::cout << std::endl;
- cout << "Not enough arguments provided." << endl;
- cout << "Usage: ./findMarkerBundles