[ros-users] How to get copy of message using MessageEvent callback?

Patrick Bouffard bouffard at eecs.berkeley.edu
Mon Oct 25 17:17:51 UTC 2010


Also a related question: if the MessageEvent style callback is used,
does (or can) this defer deserialization until getMessage is called,
or skip it altogether (by never calling getMessage)? If not is there a
way to keep a subscriber active, and a callback called when messages
are received, but to not deserialize them? It seems like, e.g.,
ShapeShifter from topic_tools might do the trick--however it doesn't
appear to be documented, is the API stable?

Thanks again,
Pat

On Sun, Oct 24, 2010 at 10:31 PM, Patrick Bouffard
<bouffard at eecs.berkeley.edu> wrote:
> I am trying out using the MessageEvent style of subscriber callback
> and having some difficulty keeping a copy of the message that I
> receive. In the old style of callback I would do something like:
>
> class MyClass
> {
> ...
> private:
> some_pkg::a_message latest_msg;
> ...
> void MyClass::subCallback(some_pkg::a_message msg)
> {
> latest_msg = msg;
> }
> ...
> }
>
> and this seems to work just fine. But when I try to do something
> similar with MessageEvent I can't get it to compile; the following
> code is patterned exactly after what is at
> http://www.ros.org/wiki/roscpp/Overview/Publishers%20and%20Subscribers#MessageEvent_.5BROS_1.1.2B-.5D:
>
>  void controlModesStatusCallback(const
> ros::MessageEvent<control_mode_status const>& event)
>  {
>    const std::string& publisher_name = event.getPublisherName();
>    const ros::M_string& header = event.getConnectionHeader();
>    ros::Time receipt_time = event.getReceiptTime();
>
>    const control_mode_statusPtr& msg = event.getMessage(); // this is line 172
>
>    ROS_INFO_STREAM("Got control mode status, from: " << publisher_name);
>    latest_mode_status[node_mode_map[publisher_name]] = msg;
>  }
>
> The error message I get is:
>
> /home/bouffard/dev/ros/ros_flyer/flyer_controller/nodes/controller.cpp:172:
> error: invalid initialization of reference of type ‘const
> flyer_controller::control_mode_statusPtr&’ from expression of type
> ‘boost::shared_ptr<const
> flyer_controller::control_mode_status_<std::allocator<void> > >’
> /home/bouffard/dev/ros/ros_flyer/flyer_controller/nodes/controller.cpp:175:
> error: no match for ‘operator=’ in
> ‘((flyer_controller::Controller*)this)->flyer_controller::Controller::latest_mode_status.std::map<_Key,
> _Tp, _Compare, _Alloc>::operator[] [with _Key =
> std::basic_string<char, std::char_traits<char>, std::allocator<char>
>>, _Tp = flyer_controller::control_mode_status_<std::allocator<void>
>>, _Compare = std::less<std::basic_string<char,
> std::char_traits<char>, std::allocator<char> > >, _Alloc =
> std::allocator<std::pair<const std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> flyer_controller::control_mode_status_<std::allocator<void> > >
>>](((const std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&)((const std::basic_string<char,
> std::char_traits<char>, std::allocator<char>
>>*)((flyer_controller::Controller*)this)->flyer_controller::Controller::node_mode_map.std::map<_Key,
> _Tp, _Compare, _Alloc>::operator[] [with _Key =
> std::basic_string<char, std::char_traits<char>, std::allocator<char>
>>, _Tp = std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >, _Compare = std::less<std::basic_string<char,
> std::char_traits<char>, std::allocator<char> > >, _Alloc =
> std::allocator<std::pair<const std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::basic_string<char, std::char_traits<char>, std::allocator<char> >
>> >](((const std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&)((const std::string*)publisher_name)))))) =
> msg’
>
> Also incidentally, I'm only using MessageEvent because I'm interested
> in knowing the name of the publisher and based on the docs this seemed
> to be the way one is meant do it. However it seems that the following
> accomplishes what I need:
>
> void controlModesStatusCallback(control_mode_status msg)
>  {
>
>    string publisher_name = (*(msg.__connection_header))["callerid"];
>    ROS_INFO_STREAM("Got control mode status, from: " << publisher_name);
>    latest_mode_status[node_mode_map[publisher_name]] = msg;
>  }
>
> .. is there any issue with using this?
>
> Thanks,
> Pat
>



More information about the ros-users mailing list