From dcd68ff7f6aa86e2d598a86b44810c799da1d2b1 Mon Sep 17 00:00:00 2001 From: William Lew Date: Tue, 28 Dec 2021 09:54:15 -0800 Subject: [PATCH] New Light Message, also bridge Color (#187) Signed-off-by: William Lew Signed-off-by: ahcorde Co-authored-by: ahcorde --- ros_ign_bridge/README.md | 2 + .../convert/ros_ign_interfaces.hpp | 14 ++ .../ros_ign_bridge/convert/std_msgs.hpp | 14 ++ .../src/convert/ros_ign_interfaces.cpp | 77 ++++++++ ros_ign_bridge/src/convert/std_msgs.cpp | 24 +++ .../src/factories/ros_ign_interfaces.cpp | 33 ++++ ros_ign_bridge/src/factories/std_msgs.cpp | 34 ++++ .../test/launch/test_ign_subscriber.launch.py | 2 + .../test/launch/test_ros_subscriber.launch.py | 2 + .../test/publishers/ign_publisher.cpp | 12 ++ .../test/publishers/ros_publisher.cpp | 15 ++ .../test/subscribers/ros_subscriber.cpp | 26 +++ ros_ign_bridge/test/test_utils.hpp | 182 ++++++++++++++++++ ros_ign_interfaces/CMakeLists.txt | 3 +- ros_ign_interfaces/README.md | 5 +- ros_ign_interfaces/msg/Light.msg | 29 +++ 16 files changed, 471 insertions(+), 3 deletions(-) create mode 100644 ros_ign_interfaces/msg/Light.msg diff --git a/ros_ign_bridge/README.md b/ros_ign_bridge/README.md index 27227780..f06f0cdc 100644 --- a/ros_ign_bridge/README.md +++ b/ros_ign_bridge/README.md @@ -9,6 +9,7 @@ service calls. Its support is limited to only the following message types: | ROS type | Ignition Transport type | |--------------------------------------|:------------------------------------:| | std_msgs/msg/Bool | ignition::msgs::Boolean | +| std_msgs/msg/ColorRGBA | ignition::msgs::Color | | std_msgs/msg/Empty | ignition::msgs::Empty | | std_msgs/msg/Float32 | ignition::msgs::Float | | std_msgs/msg/Float64 | ignition::msgs::Double | @@ -31,6 +32,7 @@ service calls. Its support is limited to only the following message types: | ros_ign_interfaces/msg/Contacts | ignition::msgs::Contacts | | ros_ign_interfaces/msg/Entity | ignition::msgs::Entity | | ros_ign_interfaces/msg/JointWrench | ignition::msgs::JointWrench | +| ros_ign_interfaces/msg/Light | ignition::msgs::Light | | rosgraph_msgs/msg/Clock | ignition::msgs::Clock | | sensor_msgs/msg/BatteryState | ignition::msgs::BatteryState | | sensor_msgs/msg/CameraInfo | ignition::msgs::CameraInfo | diff --git a/ros_ign_bridge/include/ros_ign_bridge/convert/ros_ign_interfaces.hpp b/ros_ign_bridge/include/ros_ign_bridge/convert/ros_ign_interfaces.hpp index d0354af7..dd11de60 100644 --- a/ros_ign_bridge/include/ros_ign_bridge/convert/ros_ign_interfaces.hpp +++ b/ros_ign_bridge/include/ros_ign_bridge/convert/ros_ign_interfaces.hpp @@ -19,12 +19,14 @@ #include #include #include +#include // Ignition messages #include #include #include #include +#include #include @@ -79,6 +81,18 @@ convert_ign_to_ros( const ignition::msgs::Contacts & ign_msg, ros_ign_interfaces::msg::Contacts & ros_msg); +template<> +void +convert_ros_to_ign( + const ros_ign_interfaces::msg::Light & ros_msg, + ignition::msgs::Light & ign_msg); + +template<> +void +convert_ign_to_ros( + const ignition::msgs::Light & ign_msg, + ros_ign_interfaces::msg::Light & ros_msg); + } // namespace ros_ign_bridge #endif // ROS_IGN_BRIDGE__CONVERT__ROS_IGN_INTERFACES_HPP_ diff --git a/ros_ign_bridge/include/ros_ign_bridge/convert/std_msgs.hpp b/ros_ign_bridge/include/ros_ign_bridge/convert/std_msgs.hpp index a3b163ca..bb793610 100644 --- a/ros_ign_bridge/include/ros_ign_bridge/convert/std_msgs.hpp +++ b/ros_ign_bridge/include/ros_ign_bridge/convert/std_msgs.hpp @@ -16,6 +16,7 @@ #define ROS_IGN_BRIDGE__CONVERT__STD_MSGS_HPP_ #include +#include #include #include #include @@ -26,6 +27,7 @@ // Ignition messages #include +#include #include #include #include @@ -51,6 +53,18 @@ convert_ign_to_ros( const ignition::msgs::Boolean & ign_msg, std_msgs::msg::Bool & ros_msg); +template<> +void +convert_ros_to_ign( + const std_msgs::msg::ColorRGBA & ros_msg, + ignition::msgs::Color & ign_msg); + +template<> +void +convert_ign_to_ros( + const ignition::msgs::Color & ign_msg, + std_msgs::msg::ColorRGBA & ros_msg); + template<> void convert_ros_to_ign( diff --git a/ros_ign_bridge/src/convert/ros_ign_interfaces.cpp b/ros_ign_bridge/src/convert/ros_ign_interfaces.cpp index ad3669b9..cd7571f5 100644 --- a/ros_ign_bridge/src/convert/ros_ign_interfaces.cpp +++ b/ros_ign_bridge/src/convert/ros_ign_interfaces.cpp @@ -199,4 +199,81 @@ convert_ign_to_ros( } } +template<> +void +convert_ros_to_ign( + const ros_ign_interfaces::msg::Light & ros_msg, + ignition::msgs::Light & ign_msg) +{ + convert_ros_to_ign(ros_msg.header, (*ign_msg.mutable_header())); + + ign_msg.set_name(ros_msg.name); + if (ros_msg.type == 0) { + ign_msg.set_type(ignition::msgs::Light_LightType::Light_LightType_POINT); + } else if (ros_msg.type == 1) { + ign_msg.set_type(ignition::msgs::Light_LightType::Light_LightType_SPOT); + } else if (ros_msg.type == 2) { + ign_msg.set_type( + ignition::msgs::Light_LightType::Light_LightType_DIRECTIONAL); + } + + convert_ros_to_ign(ros_msg.pose, *ign_msg.mutable_pose()); + convert_ros_to_ign(ros_msg.diffuse, *ign_msg.mutable_diffuse()); + convert_ros_to_ign(ros_msg.specular, *ign_msg.mutable_specular()); + ign_msg.set_attenuation_constant(ros_msg.attenuation_constant); + ign_msg.set_attenuation_linear(ros_msg.attenuation_linear); + ign_msg.set_attenuation_quadratic(ros_msg.attenuation_quadratic); + convert_ros_to_ign(ros_msg.direction, *ign_msg.mutable_direction()); + ign_msg.set_range(ros_msg.range); + ign_msg.set_cast_shadows(ros_msg.cast_shadows); + ign_msg.set_spot_inner_angle(ros_msg.spot_inner_angle); + ign_msg.set_spot_outer_angle(ros_msg.spot_outer_angle); + ign_msg.set_spot_falloff(ros_msg.spot_falloff); + + ign_msg.set_id(ros_msg.id); + + ign_msg.set_parent_id(ros_msg.parent_id); + + ign_msg.set_intensity(ros_msg.intensity); +} + +template<> +void +convert_ign_to_ros( + const ignition::msgs::Light & ign_msg, + ros_ign_interfaces::msg::Light & ros_msg) +{ + convert_ign_to_ros(ign_msg.header(), ros_msg.header); + + ros_msg.name = ign_msg.name(); + if (ign_msg.type() == + ignition::msgs::Light_LightType::Light_LightType_POINT) + { + ros_msg.type = 0; + } else if (ign_msg.type() == ignition::msgs::Light_LightType::Light_LightType_SPOT) { + ros_msg.type = 1; + } else if (ign_msg.type() == ignition::msgs::Light_LightType::Light_LightType_DIRECTIONAL) { + ros_msg.type = 2; + } + + convert_ign_to_ros(ign_msg.pose(), ros_msg.pose); + convert_ign_to_ros(ign_msg.diffuse(), ros_msg.diffuse); + convert_ign_to_ros(ign_msg.specular(), ros_msg.specular); + ros_msg.attenuation_constant = ign_msg.attenuation_constant(); + ros_msg.attenuation_linear = ign_msg.attenuation_linear(); + ros_msg.attenuation_quadratic = ign_msg.attenuation_quadratic(); + convert_ign_to_ros(ign_msg.direction(), ros_msg.direction); + ros_msg.range = ign_msg.range(); + ros_msg.cast_shadows = ign_msg.cast_shadows(); + ros_msg.spot_inner_angle = ign_msg.spot_inner_angle(); + ros_msg.spot_outer_angle = ign_msg.spot_outer_angle(); + ros_msg.spot_falloff = ign_msg.spot_falloff(); + + ros_msg.id = ign_msg.id(); + + ros_msg.parent_id = ign_msg.parent_id(); + + ros_msg.intensity = ign_msg.intensity(); +} + } // namespace ros_ign_bridge diff --git a/ros_ign_bridge/src/convert/std_msgs.cpp b/ros_ign_bridge/src/convert/std_msgs.cpp index a336c47d..2e54c80a 100644 --- a/ros_ign_bridge/src/convert/std_msgs.cpp +++ b/ros_ign_bridge/src/convert/std_msgs.cpp @@ -38,6 +38,30 @@ convert_ign_to_ros( ros_msg.data = ign_msg.data(); } +template<> +void +convert_ros_to_ign( + const std_msgs::msg::ColorRGBA & ros_msg, + ignition::msgs::Color & ign_msg) +{ + ign_msg.set_r(ros_msg.r); + ign_msg.set_g(ros_msg.g); + ign_msg.set_b(ros_msg.b); + ign_msg.set_a(ros_msg.a); +} + +template<> +void +convert_ign_to_ros( + const ignition::msgs::Color & ign_msg, + std_msgs::msg::ColorRGBA & ros_msg) +{ + ros_msg.r = ign_msg.r(); + ros_msg.g = ign_msg.g(); + ros_msg.b = ign_msg.b(); + ros_msg.a = ign_msg.a(); +} + template<> void convert_ros_to_ign( diff --git a/ros_ign_bridge/src/factories/ros_ign_interfaces.cpp b/ros_ign_bridge/src/factories/ros_ign_interfaces.cpp index ec9951bf..bfd634a4 100644 --- a/ros_ign_bridge/src/factories/ros_ign_interfaces.cpp +++ b/ros_ign_bridge/src/factories/ros_ign_interfaces.cpp @@ -72,6 +72,16 @@ get_factory__ros_ign_interfaces( > >("ros_ign_interfaces/msg/Contacts", ign_type_name); } + if ((ros_type_name == "ros_ign_interfaces/msg/Light" || + ros_type_name.empty()) && ign_type_name == "ignition.msgs.Light") + { + return std::make_shared< + Factory< + ros_ign_interfaces::msg::Light, + ignition::msgs::Light + > + >("ros_ign_interfaces/msg/Light", ign_type_name); + } return nullptr; } @@ -171,5 +181,28 @@ Factory< ros_ign_bridge::convert_ign_to_ros(ign_msg, ros_msg); } +template<> +void +Factory< + ros_ign_interfaces::msg::Light, + ignition::msgs::Light +>::convert_ros_to_ign( + const ros_ign_interfaces::msg::Light & ros_msg, + ignition::msgs::Light & ign_msg) +{ + ros_ign_bridge::convert_ros_to_ign(ros_msg, ign_msg); +} + +template<> +void +Factory< + ros_ign_interfaces::msg::Light, + ignition::msgs::Light +>::convert_ign_to_ros( + const ignition::msgs::Light & ign_msg, + ros_ign_interfaces::msg::Light & ros_msg) +{ + ros_ign_bridge::convert_ign_to_ros(ign_msg, ros_msg); +} } // namespace ros_ign_bridge diff --git a/ros_ign_bridge/src/factories/std_msgs.cpp b/ros_ign_bridge/src/factories/std_msgs.cpp index 05d3f19b..0ce63c6b 100644 --- a/ros_ign_bridge/src/factories/std_msgs.cpp +++ b/ros_ign_bridge/src/factories/std_msgs.cpp @@ -39,6 +39,16 @@ get_factory__std_msgs( > >("std_msgs/msg/Bool", ign_type_name); } + if ((ros_type_name == "std_msgs/msg/ColorRGBA" || + ros_type_name.empty()) && ign_type_name == "ignition.msgs.Color") + { + return std::make_shared< + Factory< + std_msgs::msg::ColorRGBA, + ignition::msgs::Color + > + >("std_msgs/msg/ColorRGBA", ign_type_name); + } if ((ros_type_name == "std_msgs/msg/Empty" || ros_type_name.empty()) && ign_type_name == "ignition.msgs.Empty") { @@ -136,6 +146,30 @@ Factory< ros_ign_bridge::convert_ign_to_ros(ign_msg, ros_msg); } +template<> +void +Factory< + std_msgs::msg::ColorRGBA, + ignition::msgs::Color +>::convert_ros_to_ign( + const std_msgs::msg::ColorRGBA & ros_msg, + ignition::msgs::Color & ign_msg) +{ + ros_ign_bridge::convert_ros_to_ign(ros_msg, ign_msg); +} + +template<> +void +Factory< + std_msgs::msg::ColorRGBA, + ignition::msgs::Color +>::convert_ign_to_ros( + const ignition::msgs::Color & ign_msg, + std_msgs::msg::ColorRGBA & ros_msg) +{ + ros_ign_bridge::convert_ign_to_ros(ign_msg, ros_msg); +} + template<> void Factory< diff --git a/ros_ign_bridge/test/launch/test_ign_subscriber.launch.py b/ros_ign_bridge/test/launch/test_ign_subscriber.launch.py index 20c98fd3..216dbf74 100644 --- a/ros_ign_bridge/test/launch/test_ign_subscriber.launch.py +++ b/ros_ign_bridge/test/launch/test_ign_subscriber.launch.py @@ -40,6 +40,7 @@ def generate_test_description(): executable='parameter_bridge', arguments=[ '/bool@std_msgs/msg/Bool@ignition.msgs.Boolean', + '/color@std_msgs/msg/ColorRGBA@ignition.msgs.Color', '/empty@std_msgs/msg/Empty@ignition.msgs.Empty', '/float@std_msgs/msg/Float32@ignition.msgs.Float', '/double@std_msgs/msg/Float64@ignition.msgs.Double', @@ -61,6 +62,7 @@ def generate_test_description(): '/entity@ros_ign_interfaces/msg/Entity@ignition.msgs.Entity', '/contact@ros_ign_interfaces/msg/Contact@ignition.msgs.Contact', '/contacts@ros_ign_interfaces/msg/Contacts@ignition.msgs.Contacts', + '/light@ros_ign_interfaces/msg/Light@ignition.msgs.Light', '/image@sensor_msgs/msg/Image@ignition.msgs.Image', '/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo', '/fluid_pressure@sensor_msgs/msg/FluidPressure@ignition.msgs.FluidPressure', diff --git a/ros_ign_bridge/test/launch/test_ros_subscriber.launch.py b/ros_ign_bridge/test/launch/test_ros_subscriber.launch.py index 19b5c85b..28ac4be4 100644 --- a/ros_ign_bridge/test/launch/test_ros_subscriber.launch.py +++ b/ros_ign_bridge/test/launch/test_ros_subscriber.launch.py @@ -40,6 +40,7 @@ def generate_test_description(): executable='parameter_bridge', arguments=[ '/bool@std_msgs/msg/Bool@ignition.msgs.Boolean', + '/color@std_msgs/msg/ColorRGBA@ignition.msgs.Color', '/empty@std_msgs/msg/Empty@ignition.msgs.Empty', '/float@std_msgs/msg/Float32@ignition.msgs.Float', '/double@std_msgs/msg/Float64@ignition.msgs.Double', @@ -61,6 +62,7 @@ def generate_test_description(): '/entity@ros_ign_interfaces/msg/Entity@ignition.msgs.Entity', '/contact@ros_ign_interfaces/msg/Contact@ignition.msgs.Contact', '/contacts@ros_ign_interfaces/msg/Contacts@ignition.msgs.Contacts', + '/light@ros_ign_interfaces/msg/Light@ignition.msgs.Light', '/image@sensor_msgs/msg/Image@ignition.msgs.Image', '/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo', '/fluid_pressure@sensor_msgs/msg/FluidPressure@ignition.msgs.FluidPressure', diff --git a/ros_ign_bridge/test/publishers/ign_publisher.cpp b/ros_ign_bridge/test/publishers/ign_publisher.cpp index bbb2a123..0081d17e 100644 --- a/ros_ign_bridge/test/publishers/ign_publisher.cpp +++ b/ros_ign_bridge/test/publishers/ign_publisher.cpp @@ -48,6 +48,16 @@ int main(int /*argc*/, char **/*argv*/) // Create a transport node and advertise a topic. ignition::transport::Node node; + // ignition::msgs::Color. + auto color_pub = node.Advertise("color"); + ignition::msgs::Color color_msg; + ros_ign_bridge::testing::createTestMsg(color_msg); + + // ignition::msgs::Light. + auto light_pub = node.Advertise("light"); + ignition::msgs::Light light_msg; + ros_ign_bridge::testing::createTestMsg(light_msg); + // ignition::msgs::Boolean. auto bool_pub = node.Advertise("bool"); ignition::msgs::Boolean bool_msg; @@ -224,6 +234,8 @@ int main(int /*argc*/, char **/*argv*/) // Publish messages at 1Hz. while (!g_terminatePub) { + color_pub.Publish(color_msg); + light_pub.Publish(light_msg); bool_pub.Publish(bool_msg); empty_pub.Publish(empty_msg); float_pub.Publish(float_msg); diff --git a/ros_ign_bridge/test/publishers/ros_publisher.cpp b/ros_ign_bridge/test/publishers/ros_publisher.cpp index 53096bd6..b1399b68 100644 --- a/ros_ign_bridge/test/publishers/ros_publisher.cpp +++ b/ros_ign_bridge/test/publishers/ros_publisher.cpp @@ -22,6 +22,7 @@ // #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +51,11 @@ int main(int argc, char ** argv) auto node = rclcpp::Node::make_shared("ros_string_publisher"); rclcpp::Rate loop_rate(1); + // std_msgs::msg::Color. + auto color_pub = node->create_publisher("color", 1000); + std_msgs::msg::ColorRGBA color_msg; + ros_ign_bridge::testing::createTestMsg(color_msg); + // std_msgs::msg::Bool. auto bool_pub = node->create_publisher("bool", 1000); std_msgs::msg::Bool bool_msg; @@ -148,6 +155,12 @@ int main(int argc, char ** argv) geometry_msgs::msg::Wrench wrench_msg; ros_ign_bridge::testing::createTestMsg(wrench_msg); + // ros_ign_interfaces::msg::Light. + auto light_pub = + node->create_publisher("light", 1000); + ros_ign_interfaces::msg::Light light_msg; + ros_ign_bridge::testing::createTestMsg(light_msg); + // ros_ign_interfaces::msg::JointWrench. auto joint_wrench_pub = node->create_publisher("joint_wrench", 1000); @@ -246,6 +259,7 @@ int main(int argc, char ** argv) while (rclcpp::ok()) { // Publish all messages. + color_pub->publish(color_msg); bool_pub->publish(bool_msg); empty_pub->publish(empty_msg); float_pub->publish(float_msg); @@ -264,6 +278,7 @@ int main(int argc, char ** argv) tf2_message_pub->publish(tf2_msg); twist_pub->publish(twist_msg); wrench_pub->publish(wrench_msg); + light_pub->publish(light_msg); joint_wrench_pub->publish(joint_wrench_msg); entity_pub->publish(entity_msg); contact_pub->publish(contact_msg); diff --git a/ros_ign_bridge/test/subscribers/ros_subscriber.cpp b/ros_ign_bridge/test/subscribers/ros_subscriber.cpp index ddd4a2c6..656e7e0e 100644 --- a/ros_ign_bridge/test/subscribers/ros_subscriber.cpp +++ b/ros_ign_bridge/test/subscribers/ros_subscriber.cpp @@ -26,6 +26,7 @@ #include "geometry_msgs/msg/vector3.hpp" #include "nav_msgs/msg/odometry.hpp" #include "rclcpp/rclcpp.hpp" +#include "ros_ign_interfaces/msg/light.hpp" #include "rosgraph_msgs/msg/clock.hpp" #include "sensor_msgs/msg/battery_state.hpp" #include "sensor_msgs/msg/camera_info.hpp" @@ -37,6 +38,7 @@ #include "sensor_msgs/msg/magnetic_field.hpp" #include "sensor_msgs/msg/point_cloud2.hpp" #include "std_msgs/msg/bool.hpp" +#include "std_msgs/msg/color_rgba.hpp" #include "std_msgs/msg/empty.hpp" #include "std_msgs/msg/float32.hpp" #include "std_msgs/msg/header.hpp" @@ -84,6 +86,18 @@ class MyTestClass typename rclcpp::Subscription::SharedPtr sub; }; +///////////////////////////////////////////////// +TEST(ROSSubscriberTest, Color) +{ + MyTestClass client("color"); + + using namespace std::chrono_literals; + ros_ign_bridge::testing::waitUntilBoolVarAndSpin( + node, client.callbackExecuted, 10ms, 200); + + EXPECT_TRUE(client.callbackExecuted); +} + ///////////////////////////////////////////////// TEST(ROSSubscriberTest, Bool) { @@ -300,6 +314,18 @@ TEST(ROSSubscriberTest, Wrench) EXPECT_TRUE(client.callbackExecuted); } +///////////////////////////////////////////////// +TEST(ROSSubscriberTest, Light) +{ + MyTestClass client("light"); + + using namespace std::chrono_literals; + ros_ign_bridge::testing::waitUntilBoolVarAndSpin( + node, client.callbackExecuted, 10ms, 200); + + EXPECT_TRUE(client.callbackExecuted); +} + ///////////////////////////////////////////////// TEST(ROSSubscriberTest, JointWrench) { diff --git a/ros_ign_bridge/test/test_utils.hpp b/ros_ign_bridge/test/test_utils.hpp index e4df1105..f486ee59 100644 --- a/ros_ign_bridge/test/test_utils.hpp +++ b/ros_ign_bridge/test/test_utils.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +119,29 @@ void waitUntilBoolVarAndSpin( /// ROS test utils ////////////////////////////////////////////////// +/// \brief Create a message used for testing. +/// \param[out] _msg The message populated. +void createTestMsg(std_msgs::msg::ColorRGBA & _msg) +{ + _msg.r = 0.2; + _msg.g = 0.4; + _msg.b = 0.6; + _msg.a = 0.8; +} + +/// \brief Compare a message with the populated for testing. +/// \param[in] _msg The message to compare. +void compareTestMsg(const std::shared_ptr & _msg) +{ + std_msgs::msg::ColorRGBA expected_msg; + createTestMsg(expected_msg); + + EXPECT_FLOAT_EQ(expected_msg.r, _msg->r); + EXPECT_FLOAT_EQ(expected_msg.g, _msg->g); + EXPECT_FLOAT_EQ(expected_msg.b, _msg->b); + EXPECT_FLOAT_EQ(expected_msg.a, _msg->a); +} + /// \brief Create a message used for testing. /// \param[out] _msg The message populated. void createTestMsg(std_msgs::msg::Bool & _msg) @@ -502,6 +527,67 @@ void createTestMsg(ros_ign_interfaces::msg::JointWrench & _msg) createTestMsg(_msg.body_2_wrench); } +/// \brief Create a message used for testing. +/// \param[out] _msg The message populated. +void createTestMsg(ros_ign_interfaces::msg::Light & _msg) +{ + createTestMsg(_msg.header); + + _msg.name = "test_light"; + _msg.type = 1; + + createTestMsg(_msg.pose); + createTestMsg(_msg.diffuse); + createTestMsg(_msg.specular); + _msg.attenuation_constant = 0.2; + _msg.attenuation_linear = 0.4; + _msg.attenuation_quadratic = 0.6; + createTestMsg(_msg.direction); + _msg.range = 25.0; + _msg.cast_shadows = true; + _msg.spot_inner_angle = 0.3; + _msg.spot_outer_angle = 0.6; + _msg.spot_falloff = 10.0; + + _msg.id = 24; + + _msg.parent_id = 6; + + _msg.intensity = 125.0; +} + +/// \brief Compare a message with the populated for testing. +/// \param[in] _msg The message to compare. +void compareTestMsg(const std::shared_ptr & _msg) +{ + ros_ign_interfaces::msg::Light expected_msg; + createTestMsg(expected_msg); + + compareTestMsg(_msg->header); + + EXPECT_EQ(expected_msg.name, _msg->name); + EXPECT_EQ(expected_msg.type, _msg->type); + + compareTestMsg(std::make_shared(_msg->pose)); + compareTestMsg(std::make_shared(_msg->diffuse)); + compareTestMsg(std::make_shared(_msg->specular)); + EXPECT_FLOAT_EQ(expected_msg.attenuation_constant, _msg->attenuation_constant); + EXPECT_FLOAT_EQ(expected_msg.attenuation_linear, _msg->attenuation_linear); + EXPECT_FLOAT_EQ(expected_msg.attenuation_quadratic, _msg->attenuation_quadratic); + compareTestMsg(std::make_shared(_msg->direction)); + EXPECT_FLOAT_EQ(expected_msg.range, _msg->range); + EXPECT_EQ(expected_msg.cast_shadows, _msg->cast_shadows); + EXPECT_FLOAT_EQ(expected_msg.spot_inner_angle, _msg->spot_inner_angle); + EXPECT_FLOAT_EQ(expected_msg.spot_outer_angle, _msg->spot_outer_angle); + EXPECT_FLOAT_EQ(expected_msg.spot_falloff, _msg->spot_falloff); + + EXPECT_EQ(expected_msg.id, _msg->id); + + EXPECT_EQ(expected_msg.parent_id, _msg->parent_id); + + EXPECT_FLOAT_EQ(expected_msg.intensity, _msg->intensity); +} + /// \brief Compare a message with the populated for testing. /// \param[in] _msg The message to compare. void compareTestMsg(const std::shared_ptr & _msg) @@ -1112,6 +1198,29 @@ void compareTestMsg(const std::shared_ptr /// Ignition::msgs test utils ////////////////////////////////////////////////// +/// \brief Create a message used for testing. +/// \param[out] _msg The message populated. +void createTestMsg(ignition::msgs::Color & _msg) +{ + _msg.set_r(0.2); + _msg.set_g(0.4); + _msg.set_b(0.6); + _msg.set_a(0.8); +} + +/// \brief Compare a message with the populated for testing. +/// \param[in] _msg The message to compare. +void compareTestMsg(const std::shared_ptr & _msg) +{ + ignition::msgs::Color expected_msg; + createTestMsg(expected_msg); + + EXPECT_EQ(expected_msg.r(), _msg->r()); + EXPECT_EQ(expected_msg.g(), _msg->g()); + EXPECT_EQ(expected_msg.b(), _msg->b()); + EXPECT_EQ(expected_msg.a(), _msg->a()); +} + /// \brief Create a message used for testing. /// \param[out] _msg The message populated. void createTestMsg(ignition::msgs::Boolean & _msg) @@ -2142,6 +2251,79 @@ void compareTestMsg(const std::shared_ptr & _ms } } +/// \brief Create a message used for testing. +/// \param[out] _msg The message populated. +void createTestMsg(ignition::msgs::Light & _msg) +{ + ignition::msgs::Header header_msg; + ignition::msgs::Pose pose_msg; + ignition::msgs::Color diffuse_msg; + ignition::msgs::Color specular_msg; + ignition::msgs::Vector3d direction_msg; + + createTestMsg(header_msg); + createTestMsg(pose_msg); + createTestMsg(diffuse_msg); + createTestMsg(specular_msg); + createTestMsg(direction_msg); + + _msg.mutable_header()->CopyFrom(header_msg); + _msg.mutable_pose()->CopyFrom(pose_msg); + _msg.mutable_diffuse()->CopyFrom(diffuse_msg); + _msg.mutable_specular()->CopyFrom(specular_msg); + _msg.mutable_direction()->CopyFrom(direction_msg); + + _msg.set_name("test_light"); + _msg.set_type(ignition::msgs::Light_LightType::Light_LightType_SPOT); + + _msg.set_attenuation_constant(0.2); + _msg.set_attenuation_linear(0.4); + _msg.set_attenuation_quadratic(0.6); + _msg.set_range(25.0); + _msg.set_cast_shadows(true); + _msg.set_spot_inner_angle(0.3); + _msg.set_spot_outer_angle(0.6); + _msg.set_spot_falloff(10.0); + + _msg.set_id(24); + + _msg.set_parent_id(6); + + _msg.set_intensity(125.0); +} + +/// \brief Compare a message with the populated for testing. +/// \param[in] _msg The message to compare. +void compareTestMsg(const std::shared_ptr & _msg) +{ + ignition::msgs::Light expected_msg; + createTestMsg(expected_msg); + + compareTestMsg(std::make_shared(_msg->header())); + compareTestMsg(std::make_shared(_msg->pose())); + compareTestMsg(std::make_shared(_msg->diffuse())); + compareTestMsg(std::make_shared(_msg->specular())); + compareTestMsg(std::make_shared(_msg->direction())); + + EXPECT_EQ(expected_msg.name(), _msg->name()); + EXPECT_EQ(expected_msg.type(), _msg->type()); + + EXPECT_FLOAT_EQ(expected_msg.attenuation_constant(), _msg->attenuation_constant()); + EXPECT_FLOAT_EQ(expected_msg.attenuation_linear(), _msg->attenuation_linear()); + EXPECT_FLOAT_EQ(expected_msg.attenuation_quadratic(), _msg->attenuation_quadratic()); + EXPECT_FLOAT_EQ(expected_msg.range(), _msg->range()); + EXPECT_EQ(expected_msg.cast_shadows(), _msg->cast_shadows()); + EXPECT_FLOAT_EQ(expected_msg.spot_inner_angle(), _msg->spot_inner_angle()); + EXPECT_FLOAT_EQ(expected_msg.spot_outer_angle(), _msg->spot_outer_angle()); + EXPECT_FLOAT_EQ(expected_msg.spot_falloff(), _msg->spot_falloff()); + + EXPECT_EQ(expected_msg.id(), _msg->id()); + + EXPECT_EQ(expected_msg.parent_id(), _msg->parent_id()); + + EXPECT_FLOAT_EQ(expected_msg.intensity(), _msg->intensity()); +} + } // namespace testing } // namespace ros_ign_bridge diff --git a/ros_ign_interfaces/CMakeLists.txt b/ros_ign_interfaces/CMakeLists.txt index 1d1082ae..7c40b036 100644 --- a/ros_ign_interfaces/CMakeLists.txt +++ b/ros_ign_interfaces/CMakeLists.txt @@ -21,6 +21,7 @@ set(msg_files "msg/Entity.msg" "msg/EntityFactory.msg" "msg/JointWrench.msg" + "msg/Light.msg" "msg/WorldControl.msg" "msg/WorldReset.msg" ) @@ -35,7 +36,7 @@ set(srv_files rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} ${srv_files} - DEPENDENCIES builtin_interfaces std_msgs geometry_msgs + DEPENDENCIES builtin_interfaces std_msgs geometry_msgs ADD_LINTER_TESTS ) diff --git a/ros_ign_interfaces/README.md b/ros_ign_interfaces/README.md index 82731d3c..f2cd7147 100644 --- a/ros_ign_interfaces/README.md +++ b/ros_ign_interfaces/README.md @@ -5,10 +5,11 @@ This package currently contains some Ignition-specific ROS message and service d ## Messages (.msg) * [Contact](msg/Contact.msg): related to [ignition::msgs::Contact](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/contact.proto). Contant info bewteen collisions in Ignition Gazebo. -* [Contacts](msg/Contacts.msg): related to [ignition::msgs::Contacts](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/contacts.proto).a list of contact. +* [Contacts](msg/Contacts.msg): related to [ignition::msgs::Contacts](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/contacts.proto). A list of contacts. * [Entity](msg/Entity.msg): related to [ignition::msgs::Entity](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/entity.proto). Entity of Ignition Gazebo. * [EntityFactory](msg/EntityFactory.msg): related to [ignition::msgs::EntityFactory](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/entity_factory.proto). Message to create a new entity. -* [WorldControl](msg/WorldControl.msg): related to [ignition::msgs::WorldControl](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/world_control.proto). Message to control world of Ingition Gazebo. +* [Light](msg/Light.msg): related to [ignition::msgs::Light](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/light.proto). Light info in Ignition Gazebo. +* [WorldControl](msg/WorldControl.msg): related to [ignition::msgs::WorldControl](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/world_control.proto). Message to control world of Ignition Gazebo. * [WorldReset](msg/WorldReset.msg): related to [ignition::msgs::WorldReset](https://github.com/ignitionrobotics/ign-msgs/blob/ign-msgs7/proto/ignition/msgs/world_reset.proto). Reset time and model of simulation. ## Services (.srv) diff --git a/ros_ign_interfaces/msg/Light.msg b/ros_ign_interfaces/msg/Light.msg new file mode 100644 index 00000000..911e20bd --- /dev/null +++ b/ros_ign_interfaces/msg/Light.msg @@ -0,0 +1,29 @@ +std_msgs/Header header # Optional header data + +string name # Light name + +# Light type: constant definition +uint8 POINT = 0 +uint8 SPOT = 1 +uint8 DIRECTIONAL = 2 + +uint8 type # Light type (from constant definitions) + +geometry_msgs/Pose pose # Light pose +std_msgs/ColorRGBA diffuse # Light diffuse emission +std_msgs/ColorRGBA specular # Light specular emission +float32 attenuation_constant # Constant variable in attenuation formula +float32 attenuation_linear # Linear variable in attenuation formula +float32 attenuation_quadratic # Quadratic variable in attenuation formula +geometry_msgs/Vector3 direction # Light direction +float32 range # Light range +bool cast_shadows # Enable/disable shadow casting +float32 spot_inner_angle # Spotlight inner cone angle +float32 spot_outer_angle # Spotlight outer cone angle +float32 spot_falloff # Falloff between inner and outer cone + +uint32 id # Unique id of the light + +uint32 parent_id # Unique id of the light's parent + +float32 intensity # Light intensity