Ask Your Question

Philip's profile - activity

2018-10-15 09:23:49 -0600 received badge  Nice Answer (source)
2017-10-17 22:59:26 -0600 received badge  Good Answer (source)
2016-03-30 10:14:10 -0600 received badge  Nice Answer (source)
2015-06-12 15:51:39 -0600 received badge  Good Answer (source)
2015-05-31 10:39:06 -0600 received badge  Good Answer (source)
2015-05-19 21:06:33 -0600 received badge  Great Answer (source)
2015-05-19 21:06:33 -0600 received badge  Guru (source)
2014-04-02 16:40:10 -0600 received badge  Great Answer (source)
2014-04-02 16:40:10 -0600 received badge  Guru (source)
2014-01-28 17:29:59 -0600 marked best answer Best practice for online re-configuration between nodes

Dear all,

I'm looking for the best way to achieve the following (in cpp on Fuerte).

At the moment, I have one node which should be dynamically reconfigurable (i.e.: start, stop, set camera frame rate). In the long run, there will be many nodes that should be configurable by other nodes, often by one node switching the system into different states. The current state of each node should be accessible by all other nodes. What's the best design to achieve this?

My ideas so far:

  1. Use dynamic_reconfigure in each node.
  2. Provide services for all configurations in each node.
  3. Use the parameter_server for exchange of parameters and offer an updateFromServer()-service in each node. Other nodes set the new parameters on the server and then trigger the service to reconfigure accordingly. Probably not very clever as there can be inconsistencies / false assumptions about the current configurations.
  4. Use the parameter server with different parameters for the desired (new) configuration and the actual one, again coupled with a updateFromServer()-service. Other nodes set the desired parameter and call the service for starting the reconfiguration. After reconfiguring, the node updates the actual values on the parameter server (where the caller can check, if needed).

In case of three and four, I could probably use a regular getParamCached() call instead of the service (?).

Do any of these seem reasonable? Do you have comments on possible benefits/downsides of using on or another, e.g. in terms of performance, manageability of code (including n services of different other nodes), best practices? Or is there some other method that I didn't discover yet?

I'd appreciate your comments or recommendations!

Regards,

Philip

P.S.: If there's any changes between Fuerte and Groovy that may benefit my use-case, I'd probably consider upgrading.


EDIT (in reply to comments): I am not looking for setting and reading a configuration state for the whole system, for which a nice solution was already given here. I'm rather looking for a way to be able to access and configure each node's parameters on their own during runtime. Thanks for all your input!


EDIT (out of curiosity): In this tutorial, turtlesim is re-configured at runtime via something like method 3 as described above (this is probably where I got that idea in the first place). Does anybody know a specific reason why it is done this way?

2013-11-15 03:13:49 -0600 commented answer A subscriber error

To anyone reading this answer from @pelment: Callbacks can be class methods (which in many cases is preferable). You just have to put attention to setting it up in a way that the subscriber doesn't go out of scope (and use the syntax for class-callbacks from the publisher/subscriber tutorial).

2013-11-14 10:36:04 -0600 received badge  Guru (source)
2013-11-12 03:19:40 -0600 received badge  Nice Answer (source)
2013-09-17 01:47:55 -0600 answered a question problem with custom point cloud type

Just out of my head, it's been a couple of months: I stumbled upon something similar and it wasn't because of the custom type, but of how I used the publisher. Check if you

  • pass the correct object
  • template the publisher correctly
  • and similar stuff...

Hope this helps!


EDIT: Just looked it up. Here's the relevant parts of my code copied together:

ros::Publisher myPublisher;
sensor_msgs::PointCloud2::Ptr cloudPtr;
<fill the cloud>
myPublisher = n.advertise<sensor_msgs::PointCloud2>("topic/name", 10);
myPublisher.publish(cloudPtr);

However, I directly fill the sensor_msgs::PointCloud2 datatype of ROS instead of using the PCL one.

2013-08-14 04:39:46 -0600 commented answer Is anyone else thinking about wrapping the leap for ROS?

+1 to be interested in a ros node, especially one working in Fuerte ;-)

2013-07-17 11:55:51 -0600 edited question marker array not visible in rviz but is getting published..

I am trying display marker array in rviz. The marker is published succesfully but is not visible in rviz. The code is below:

int
main (int argc, char** argv)
{

visualization_msgs::Marker marker;
visualization_msgs::MarkerArray marker_array_msg;

  // Initialize ROS
  ros::init (argc, argv, "pcl_tabletop");
  ros::NodeHandle nh;

  pub_marker = nh.advertise<visualization_msgs::MarkerArray>("normals_marker_array", 100);
//pub_marker1 = nh.advertise<visualization_msgs::Marker>("normals_marker", 0);
/*while(1)
{

marker.header.frame_id = "base_link";
marker.header.stamp = ros::Time();
marker.ns = "my_namespace";
marker.id = 120;
marker.type = visualization_msgs::Marker::SPHERE;
marker.action = visualization_msgs::Marker::ADD;
marker.pose.position.x = 1;
marker.pose.position.y = 1;
marker.pose.position.z = 1;
marker.pose.orientation.x = 0.0;
marker.pose.orientation.y = 0.0;
marker.pose.orientation.z = 0.0;
marker.pose.orientation.w = 1.0;
marker.scale.x = 1;
marker.scale.y = 0.1;
marker.scale.z = 0.1;
marker.color.a = 1.0;
marker.color.r = 1.0;
marker.color.g = 0.0;
marker.color.b = 0.0;

//pub_marker.publish(marker_array_msg);

pub_marker1.publish(marker);
}*/

marker_array_msg.markers.resize(5);//final->width * final->height);
for ( int i = 0; i < 5; i++)
{
    marker_array_msg.markers[i].header.frame_id = "base_link";
    marker_array_msg.markers[i].header.stamp = ros::Time();
    marker_array_msg.markers[i].ns = "my_namespace";
    marker_array_msg.markers[i].id = i;
    marker_array_msg.markers[i].type = visualization_msgs::Marker::SPHERE;
    marker_array_msg.markers[i].action = visualization_msgs::Marker::ADD;
    marker_array_msg.markers[i].pose.position.x = i+50;
    marker_array_msg.markers[i].pose.position.y = 50+i;
    marker_array_msg.markers[i].pose.position.z = 10+i;
    marker_array_msg.markers[i].pose.orientation.x = 0.0;
    marker_array_msg.markers[i].pose.orientation.y = 0.0;
    marker_array_msg.markers[i].pose.orientation.z = 0.0;
    marker_array_msg.markers[i].pose.orientation.w = 1.0;
    marker_array_msg.markers[i].scale.x = 1;
    marker_array_msg.markers[i].scale.y = 0.1;
    marker_array_msg.markers[i].scale.z = 0.1;
    marker_array_msg.markers[i].color.a = 1.0;
    marker_array_msg.markers[i].color.r = 0.0;
    if (i == 0)
    {
        marker_array_msg.markers[i].color.g = 0.1;
    }
    else
    {
        marker_array_msg.markers[i].color.g = i * 0.15;
    }
    marker_array_msg.markers[i].color.b = 0.0;

     //marker_array_msg.markers.push_back(mark);
}
while(1)
{
 pub_marker.publish(marker_array_msg);
}

  // Spin
  ros::spin ();
}

I tried both Marker and MarkerArray types but its not visible in rviz. Am i doing something wrong when assigning values to marker array ?? This was my first try with marker array further actually i want to display segmented pcl data as marker array.

Any idea what is wrong please :)

2013-07-16 21:56:21 -0600 received badge  Great Answer (source)
2013-07-16 13:29:24 -0600 received badge  Good Answer (source)
2013-07-16 06:50:24 -0600 received badge  Nice Answer (source)
2013-07-16 02:23:39 -0600 answered a question What is the benefit & target of using ROS?
  1. Yes, ROS can be used to control robots.
  2. ROS also includes packages for simulation.

See http://answers.ros.org/question/61939/why-use-ros/ and http://answers.ros.org/question/33811/why-choose-ros/ for some more information about what ROS can do / can be used for.

As first steps, I'd suggest to head over to ros.org and have a look at the tutorials and projects.

2013-07-14 06:04:20 -0600 commented answer pcl detecting planes in the map

If you use the code you posted on dropbox, this is the correct behaviour. What happens is the following: You enter the callback, pcl visualizer spins until the viewer is closed. Afterwards, the publisher is invoked. Replace 'while (!viewer->wasStopped ()) {...}' by a simple 'viewer->spinOnce (100)'.

2013-07-12 22:52:03 -0600 commented answer pcl detecting planes in the map

Strange! I fear that I have no immediate idea... can you verify that the final_cloud which you send to RViz is created correctly? E.g. display the number of points by something like printf(final_cloud.fields.count)

2013-07-12 12:08:52 -0600 commented answer pcl detecting planes in the map

I reformatted your code for easier readability. Can you give information about what doesn't work (see my question)?

2013-07-12 12:06:24 -0600 edited question pcl detecting planes in the map

I am new to pcl, i would like to detect/segment all the planar surfaces ex: tables. I tried the tutorial :http://pointclouds.org/documentation/tutorials/extract_indices.php#extract-indices

and used the extracted points to visualize in rviz but i don not see the planar surfaces clearly. I guess i am displaying wrong points ..

Could someone explain that tutorial or tell how can i detect planar surfaces in pcl2 format and further use those pcl2 ??

Update: I have attached the code:

#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
// PCL specific includes
#include <pcl/ros/conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>
ros::Publisher pub;

void process_cloud (const sensor_msgs::PointCloud2ConstPtr& input)
{
  // ... do data processing

sensor_msgs::PointCloud2::Ptr cloud_blob (new sensor_msgs::PointCloud2), cloud_filtered_blob (new sensor_msgs::PointCloud2);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>), cloud_p (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);
sensor_msgs::PointCloud2::Ptr final_cloud (new sensor_msgs::PointCloud2);


  // Create the filtering object: downsample the dataset using a leaf size of 1cm
  pcl::VoxelGrid<sensor_msgs::PointCloud2> sor;

  sor.setInputCloud (input); // input is the pcl2 received from /depthcam.
  sor.setLeafSize (0.01f, 0.01f, 0.01f);
  sor.filter (*cloud_filtered_blob);

  // Convert to the templated PointCloud
  pcl::fromROSMsg (*cloud_filtered_blob, *cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << " data points." << std::endl;

  // Write the downsampled version to disk
  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("downsampled.pcd", *cloud_filtered, false);

  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());

  // Create the segmentation object
  pcl::SACSegmentation<pcl::PointXYZ> seg;

  // Optional
  seg.setOptimizeCoefficients (true);

  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (1000);
  seg.setDistanceThreshold (0.01);

  // Create the filtering object
  pcl::ExtractIndices<pcl::PointXYZ> extract;

  int i = 0, nr_points = (int) cloud_filtered->points.size ();
  // While 30% of the original cloud is still there
  while (cloud_filtered->points.size () > 0.3 * nr_points)
  {
    // Segment the largest planar component from the remaining cloud
    seg.setInputCloud (cloud_filtered);
    seg.segment (*inliers, *coefficients);
    if (inliers->indices.size () == 0)
    {
      std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
      break;
    }

    // Extract the inliers
    extract.setInputCloud (cloud_filtered);
    extract.setIndices (inliers);
    extract.setNegative (false);
    extract.filter (*cloud_p);
    std::cerr << "PointCloud representing the planar component: " << cloud_p->width * cloud_p->height << " data points." << std::endl;

    std::stringstream ss;
    ss << "new_pcl" << i << ".pcd";
    writer.write<pcl::PointXYZ> (ss.str (), *cloud_p, false);

    // Create the filtering object
    extract.setNegative (true);
    extract.filter (*cloud_f);
    cloud_filtered.swap (cloud_f);
    i++;
  }


  // conbert to sensormsg type
  pcl::toROSMsg (*cloud_p, *final_cloud);

//sensor_msgs::PointCloud2 output;
  // Publish the data
 pub.publish (final_cloud); // publish the new pcl
}

int
main (int argc, char** argv)
{
  // Initialize ROS
  ros::init (argc, argv, "pcl_tabletop");
  ros::NodeHandle nh;

  // Create a ROS subscriber for the input point cloud
  ros::Subscriber sub = nh.subscribe ("depthcam", 1, process_cloud); // depthcam is the ...
(more)
2013-07-11 10:03:41 -0600 answered a question pcl detecting planes in the map

I guess this question would be more suited to the pcl user mailinglist as it is not really related to ROS.

Did you have a look at the plane segmentation tutorial of PCL?


Based on the information so far, it could be lots of reasons (wrong computation, error in publishing the result, ...). Can you be a little more specific about what doesn't work? What exactly do you see in RViz (no points / wrong points / "almost right points")? Can you verify that PCL segments the correct points, e.g. by displaying the result in PCL visualizer? Adding the code for publishing to your question might also help.

2013-07-11 10:00:55 -0600 answered a question Openni+Kinect+Other Machines

To my knowledge, this is not possible with just OpenNI (which was not developed for this usecase).

You might look into the possibility to install something on both machines which allows you to forward the USB-data from the BeagleBone to a virtual USB-port on the laptop - I don't know if there are solutions for this. Afaik some router manufacturers allow for this in order to access printers attached to the router from any connected PC as if it were connected locally.

Even if it is possible, you'd probably have to use a GBit-network connection as a Kinect uses about 60% of the available USB-bandwidth (which should be around 480 MBit/s, so 250+ used by the Kinect).

2013-07-10 16:13:05 -0600 received badge  Nice Answer (source)
2013-07-08 06:44:28 -0600 received badge  Good Answer (source)
2013-06-29 04:25:59 -0600 commented question Installing PCL 1.7 (trunk) on ROS Groovy

Did you follow the description at http://www.ros.org/wiki/pcl17 ? If so, can you give any error messages or similar?

2013-06-25 11:26:52 -0600 answered a question How to troubleshoot network delay

Assuming wlan standard 802.11b, the maximal bandwith is 11 MBit/s = 1,375 MByte/s. If one kinect frame amounts to 700kBytes, 2 fps would be the upper max. Using wlan standard 802.11g, 22 MBit/s = 2,75 MByte/s = 4fps would be realistic. So I would say that your 3 fps seem to be normal, yes.

depending on your scenario, you could try to separate data acquisition and processing: send only the raw data (rgb, depth map) over the network and assemble the full XYZRGB point cloud at the receivers end.

2013-06-24 14:17:06 -0600 commented answer publishing camera point clouds in rviz

Glad to hear :-) As usual, please mark the answer as "accepted" (round check mark on the left) so it can be closed. Thanks!

2013-06-24 05:29:44 -0600 received badge  Nice Answer (source)
2013-06-24 04:51:50 -0600 received badge  Nice Answer (source)
2013-06-24 04:22:34 -0600 commented answer publisher not publishing on topic

Ah, thanks for the hint about getNumSubscribers! I wasn't aware of that :-)

2013-06-24 02:09:48 -0600 answered a question publisher not publishing on topic

My first guess: you try to publish while the publisher is not fully set up. Can you try waiting for a second (e.g. using usleep(1000*1000)) between creating your publisher and sending the first message?

2013-06-23 22:40:43 -0600 answered a question Is spinOnce needed?

For single-threaded nodes:

If you have an infinite loop of your own that does some processing, use spinOnce() somewhere in the loop. This allows ROS to process the callbacks for queued messages - if you don't include it, your callbacks will never be called and none of your messages will be published.

If all your calculations are performed in callbacks and you don't need an infinite loop for your custom processing, just use spin() which continuously pumps for callbacks.

2013-06-23 21:54:11 -0600 answered a question publishing camera point clouds in rviz

Have you set the frame_id of the header of the pointcloud-message?

clusteredScene->header.frame_id = "my_frame" should probably do the trick.

See pointcloud2 message definition and header message definition for further details on the datatypes.

2013-06-20 05:41:55 -0600 received badge  Citizen Patrol (source)
2013-06-18 03:27:50 -0600 answered a question Roslaunch can't find my node

I fiddled around with this issue as well: tried different ways to set up parameters when using ssh (.ssh/environment-file, ...), tried to load my configuration at different places, but to no avail.

My current working solution now looks like this:

  • As before, there is a shell script (named ros_conf.sh) in my ros-workspace (~/ros_workspace) that exports the ROS-variables of interest: ROS_IP, ROS_MASTER, ROS_PACKAGE_PATH, ...
  • In ~/.bashrc, the last two lines execute the ROS specific scripts (so interactive shells are fully usable with ROS):
source /opt/ros/fuerte/setup.bash
source ~/ros_workspace/ros_conf.sh
  • The file opt/ros/fuerte/env.sh executes both scripts:

#!/bin/sh

if [ $# -eq 0 ] ; then
    /bin/echo "Entering environment at /opt/ros/fuerte"
    . /opt/ros/fuerte/setup.sh
    . /home/MY_USERNAME/ros_workspace/ros_conf.sh
    $SHELL
    /bin/echo "Exiting build environment at /opt/ros/fuerte"
else
    . /opt/ros/fuerte/setup.sh
    . /home/MY_USERNAME/ros_workspace/ros_conf.sh
    exec "$@"
fi

Voila! Looks to be working until now :-)

2013-06-11 22:18:13 -0600 answered a question streaming pointcloud to remote workstation

In our setup, we've split the openni_launch-launch-file into two separate launch-files:

  • The one running on the machine which is connected to the kinect (in your case: on the robot) only loads the driver and publishes raw images and the tf-data
  • On a remote machine, image_proc is launched which calculates and publishes the actual point clouds

This way, only the raw 2d data (depth/image_raw, rgb/image_raw) is transmitted over the network.

2013-06-11 03:26:33 -0600 commented answer write in a vector through the same (ROS) callback using boost::bind (C++)

The subscribers aren't necessarily called in any order, at least in none that you should rely on. When the callback function is invoked (because a message was received) and some value has to be saved at a specific "position" in your vector, you have to provide that information to the callback.