@@ -33,7 +33,12 @@ SOFTWARE.
33
33
#include < mqtt_client/MqttClient.h>
34
34
#include < mqtt_client/RosMsgType.h>
35
35
#include < pluginlib/class_list_macros.h>
36
+ #include < ros/message_traits.h>
37
+ #include < std_msgs/Bool.h>
38
+ #include < std_msgs/Float32.h>
36
39
#include < std_msgs/Float64.h>
40
+ #include < std_msgs/Int32.h>
41
+ #include < std_msgs/String.h>
37
42
#include < xmlrpcpp/XmlRpcException.h>
38
43
#include < xmlrpcpp/XmlRpcValue.h>
39
44
@@ -537,18 +542,37 @@ void MqttClient::mqtt2ros(mqtt::const_message_ptr mqtt_msg,
537
542
538
543
void MqttClient::mqtt2primitive (mqtt::const_message_ptr mqtt_msg) {
539
544
540
- bool found_primitive = false ;
545
+ std::string mqtt_topic = mqtt_msg->get_topic ();
546
+ Mqtt2RosInterface& mqtt2ros = mqtt2ros_[mqtt_topic];
541
547
const std::string str_msg = mqtt_msg->to_string ();
542
548
549
+ bool found_primitive = false ;
550
+ std::string msg_type_md5;
551
+ std::string msg_type_name;
552
+ std::string msg_type_definition;
553
+ std::vector<uint8_t > msg_buffer;
554
+
543
555
// check for bool
544
556
if (!found_primitive) {
545
557
std::string bool_str = str_msg;
546
558
std::transform (str_msg.cbegin (), str_msg.cend (), bool_str.begin (),
547
559
::tolower);
548
560
if (bool_str == " true" || bool_str == " false" ) {
549
- found_primitive = true ;
561
+
550
562
bool bool_msg = (bool_str == " true" );
551
- NODELET_INFO (" Got bool: %d" , bool_msg);
563
+
564
+ // construct and serialize ROS message
565
+ std_msgs::Bool msg;
566
+ msg.data = bool_msg;
567
+ serializeRosMessage (msg, msg_buffer);
568
+
569
+ // collect ROS message type information
570
+ msg_type_md5 = ros::message_traits::MD5Sum<std_msgs::Bool>::value ();
571
+ msg_type_name = ros::message_traits::DataType<std_msgs::Bool>::value ();
572
+ msg_type_definition =
573
+ ros::message_traits::Definition<std_msgs::Bool>::value ();
574
+
575
+ found_primitive = true ;
552
576
}
553
577
}
554
578
@@ -558,8 +582,19 @@ void MqttClient::mqtt2primitive(mqtt::const_message_ptr mqtt_msg) {
558
582
try {
559
583
const int int_msg = std::stoi (str_msg, &pos);
560
584
if (pos == str_msg.size ()) {
585
+
586
+ // construct and serialize ROS message
587
+ std_msgs::Int32 msg;
588
+ msg.data = int_msg;
589
+ serializeRosMessage (msg, msg_buffer);
590
+
591
+ // collect ROS message type information
592
+ msg_type_md5 = ros::message_traits::MD5Sum<std_msgs::Int32>::value ();
593
+ msg_type_name = ros::message_traits::DataType<std_msgs::Int32>::value ();
594
+ msg_type_definition =
595
+ ros::message_traits::Definition<std_msgs::Int32>::value ();
596
+
561
597
found_primitive = true ;
562
- NODELET_INFO (" Got int: %d" , int_msg);
563
598
}
564
599
} catch (const std::invalid_argument& ex) {
565
600
} catch (const std::out_of_range& ex) {
@@ -572,17 +607,66 @@ void MqttClient::mqtt2primitive(mqtt::const_message_ptr mqtt_msg) {
572
607
try {
573
608
const float float_msg = std::stof (str_msg, &pos);
574
609
if (pos == str_msg.size ()) {
610
+
611
+ // construct and serialize ROS message
612
+ std_msgs::Float32 msg;
613
+ msg.data = float_msg;
614
+ serializeRosMessage (msg, msg_buffer);
615
+
616
+ // collect ROS message type information
617
+ msg_type_md5 = ros::message_traits::MD5Sum<std_msgs::Float32>::value ();
618
+ msg_type_name =
619
+ ros::message_traits::DataType<std_msgs::Float32>::value ();
620
+ msg_type_definition =
621
+ ros::message_traits::Definition<std_msgs::Float32>::value ();
622
+
575
623
found_primitive = true ;
576
- NODELET_INFO (" Got float: %f" , float_msg);
577
624
}
578
625
} catch (const std::invalid_argument& ex) {
579
626
} catch (const std::out_of_range& ex) {
580
627
}
581
628
}
582
629
630
+ // fall back to string
583
631
if (!found_primitive) {
584
- NODELET_INFO (" Got string: %s" , str_msg.c_str ());
632
+
633
+ // construct and serialize ROS message
634
+ std_msgs::String msg;
635
+ msg.data = str_msg;
636
+ serializeRosMessage (msg, msg_buffer);
637
+
638
+ // collect ROS message type information
639
+ msg_type_md5 = ros::message_traits::MD5Sum<std_msgs::String>::value ();
640
+ msg_type_name = ros::message_traits::DataType<std_msgs::String>::value ();
641
+ msg_type_definition =
642
+ ros::message_traits::Definition<std_msgs::String>::value ();
643
+ }
644
+
645
+ // if ROS message type has changed
646
+ if (msg_type_md5 != mqtt2ros.ros .shape_shifter .getMD5Sum ()) {
647
+
648
+ // configure ShapeShifter
649
+ mqtt2ros.ros .shape_shifter .morph (msg_type_md5, msg_type_name,
650
+ msg_type_definition, " " );
651
+
652
+ // advertise with ROS publisher
653
+ mqtt2ros.ros .publisher .shutdown ();
654
+ mqtt2ros.ros .publisher = mqtt2ros.ros .shape_shifter .advertise (
655
+ node_handle_, mqtt2ros.ros .topic , mqtt2ros.ros .queue_size ,
656
+ mqtt2ros.ros .latched );
657
+
658
+ NODELET_INFO (" ROS publisher message type on topic '%s' set to '%s'" ,
659
+ mqtt2ros.ros .topic .c_str (), msg_type_name.c_str ());
585
660
}
661
+
662
+ // publish via ShapeShifter
663
+ ros::serialization::OStream msg_stream (msg_buffer.data (), msg_buffer.size ());
664
+ NODELET_DEBUG (
665
+ " Sending ROS message of type '%s' from MQTT broker to ROS topic '%s' ..." ,
666
+ mqtt2ros.ros .shape_shifter .getDataType ().c_str (),
667
+ mqtt2ros.ros .topic .c_str ());
668
+ mqtt2ros.ros .shape_shifter .read (msg_stream);
669
+ mqtt2ros.ros .publisher .publish (mqtt2ros.ros .shape_shifter );
586
670
}
587
671
588
672
0 commit comments