Publisher gives segmentation fault unless message is defined in a "parent scope"

asked 2018-08-10 04:59:24 -0500

Thomash gravatar image

Hi,

A peculiar bug occurred while making a simple listener/publisher for a visualization application.

I am using boost::function to pass a lambda-function; which might be a bit odd, but I do not see how this could give me a segmentation error or whether it is something different..

So the following gives a segmentation error when it tries to publish the message:

#include ....

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

    auto pose_pub   = n.advertise<geometry_msgs::PoseStamped>("/pose", 10); 
    odometry inertial_odom; 

    boost::function<void (const sensor_msgs::Imu&)> callback = 
        [&] (const sensor_msgs::Imu& msg) {
            Eigen::Vector3d a, g;
            a << msg.linear_acceleration.x, msg.linear_acceleration.y, msg.linear_acceleration.z;
            g << msg.angular_velocity.x, msg.angular_velocity.y, msg.angular_velocity.z;
            uint64_t t = msg.header.stamp.toNSec(); 

            if (inertial_odom.imu(a,g,t))
            {
                auto state_vector = inertial_odom.pose();
                geometry_msgs::PoseStamped poseStamped;            
                poseStamped.header.frame_id = "map";
                poseStamped.header.stamp = msg.header.stamp;
                poseStamped.pose.position.x = state_vector(0);
                poseStamped.pose.position.y = state_vector(1);
                poseStamped.pose.position.z = state_vector(2);
                poseStamped.pose.orientation.w = state_vector(3);
                poseStamped.pose.orientation.x = state_vector(4);
                poseStamped.pose.orientation.y = state_vector(5);
                poseStamped.pose.orientation.z = state_vector(6);

                pose_pub.publish(poseStamped);
            }
    };
    auto imu_sub    = n.subscribe<sensor_msgs::Imu>("/imu", 1000, callback);
    ros::spin();
}

while the following does not:

#include ....

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

    auto pose_pub   = n.advertise<geometry_msgs::PoseStamped>("/pose", 10);

    geometry_msgs::PoseStamped poseStamped;
    poseStamped.header.frame_id = "map";

    odometry inertial_odom; 

    boost::function<void (const sensor_msgs::Imu&)> callback = 
        [&] (const sensor_msgs::Imu& msg) {
            Eigen::Vector3d a, g;
            a << msg.linear_acceleration.x, msg.linear_acceleration.y, msg.linear_acceleration.z;
            g << msg.angular_velocity.x, msg.angular_velocity.y, msg.angular_velocity.z;
            uint64_t t = msg.header.stamp.toNSec(); 

            if (inertial_odom.imu(a,g,t))
            {
                auto state_vector = inertial_odom.pose();
                poseStamped.header.stamp = msg.header.stamp;
                poseStamped.pose.position.x = state_vector(0);
                poseStamped.pose.position.y = state_vector(1);
                poseStamped.pose.position.z = state_vector(2);
                poseStamped.pose.orientation.w = state_vector(3);
                poseStamped.pose.orientation.x = state_vector(4);
                poseStamped.pose.orientation.y = state_vector(5);
                poseStamped.pose.orientation.z = state_vector(6);

                pose_pub.publish(poseStamped);
            }
    };
    auto imu_sub    = n.subscribe<sensor_msgs::Imu>("/imu", 1000, callback);
    ros::spin();
}

I toyed around with different message-type, but it does not change the result... Any ideas?

edit retag flag offensive close merge delete

Comments

1

Two things:

  1. last time I tried this, I did not need to use boost::function to pass a lambda to NodeHandle::subscribe(..), do you have a particular reason for wanting to use it? auto worked fine for me.
  2. backtrace?

This might have something to do with poseStamped having gone ..

gvdhoorn gravatar image gvdhoorn  ( 2018-08-10 05:51:52 -0500 )edit

.. out of scope before it's actually published, and ROS internals trying to use a dangling reference (as much as those exist).

Some interesting links: passing functions to functions and ..

gvdhoorn gravatar image gvdhoorn  ( 2018-08-10 06:02:28 -0500 )edit

hi,

Thanks for those two links; they look highly relevant.. Using auto seemed to work, then I did something and now I keep getting an error.. I will retrace my steps and comment once I have something working :-)

Thomash gravatar image Thomash  ( 2018-08-10 06:41:47 -0500 )edit

ps; this is the main complaint when using auto for now: error: no match for call to .... BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));

Thomash gravatar image Thomash  ( 2018-08-10 06:47:02 -0500 )edit

As for using lambda's; no success. (also here https://stackoverflow.com/questions/4... ). As for the return value of the lambda and seg fault.. also didn't work yet.. I am going to look at it some more later.

Thomash gravatar image Thomash  ( 2018-08-10 07:59:25 -0500 )edit

Little update on the auto-lambda-callback; it stumbled upon me that ros uses xx::yy::ConstPtr when passing messages; while in the lambda I defined the function argument as reference and use it as such.. now this is ok; but it does not work with auto, if I treat it as ConstPtr (e.g. *msg), auto works

Thomash gravatar image Thomash  ( 2018-08-30 15:44:56 -0500 )edit