Skip to content

Commit

Permalink
Merge pull request #1 from Boeing/msgs_package_refactor
Browse files Browse the repository at this point in the history
Created msgs package
  • Loading branch information
RoBeau authored Nov 10, 2023
2 parents 1db6c50 + 1b1f0b9 commit b5d01c2
Show file tree
Hide file tree
Showing 19 changed files with 368 additions and 296 deletions.
File renamed without changes.
File renamed without changes.
30 changes: 5 additions & 25 deletions CMakeLists.txt → ...bo_model_attachment_plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ find_package(gazebo_msgs REQUIRED)
find_package(gazebo_ros REQUIRED)
find_package(std_msgs REQUIRED)
find_package(gazebo_dev REQUIRED)
find_package(Boost REQUIRED)

# Locate msg and srv files
set(srv_files "srv/Attach.srv" "srv/Detach.srv")
find_package(gazebo_model_attachment_plugin_msgs)

#
# Install python module and scripts
Expand All @@ -27,8 +24,6 @@ ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR src/${PROJECT_NAME})

include_directories(include)

# Generate msg and srv interfaces
rosidl_generate_interfaces(${PROJECT_NAME} ${srv_files})
ament_export_dependencies(rosidl_default_runtime)

add_library(${PROJECT_NAME}_lib SHARED src/${PROJECT_NAME}.cpp)
Expand All @@ -37,18 +32,10 @@ target_include_directories(
${PROJECT_NAME}_lib PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>
)

ament_target_dependencies(${PROJECT_NAME}_lib rclcpp gazebo_msgs gazebo_ros std_msgs gazebo_dev)
ament_export_dependencies(gazebo_dev rclcpp gazebo_msgs gazebo_ros std_msgs)

# Include interfaces generated in this package
rosidl_target_interfaces(${PROJECT_NAME}_lib ${PROJECT_NAME} "rosidl_typesupport_cpp")

ament_export_targets(ModelAttachment HAS_LIBRARY_TARGET)

ament_export_include_directories(include)
ament_export_libraries(${PROJECT_NAME}_lib)

install(DIRECTORY include DESTINATION include)
ament_target_dependencies(${PROJECT_NAME}_lib
rclcpp
gazebo_ros
gazebo_model_attachment_plugin_msgs)

install(
TARGETS ${PROJECT_NAME}_lib
Expand All @@ -60,18 +47,11 @@ install(
DESTINATION include
)

#
# Add ros tests
#
# enable_testing() find_file(NOSETESTS_EXECUTABLE nosetests) add_test(nosetests "${NOSETESTS_EXECUTABLE}" -v
# --with-xunit)

# Add Tests
if(BUILD_TESTING)
install(DIRECTORY test DESTINATION share/${PROJECT_NAME})
find_package(launch_testing_ament_cmake REQUIRED)
add_launch_test(test/test_plugin.test.py)

endif()

ament_package()
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <gazebo_model_attachment_plugin/srv/attach.hpp>
#include <gazebo_model_attachment_plugin/srv/detach.hpp>
#include <gazebo_model_attachment_plugin_msgs/srv/attach.hpp>
#include <gazebo_model_attachment_plugin_msgs/srv/detach.hpp>
#include <rclcpp/rclcpp.hpp>

#include <gazebo/common/Events.hh>
Expand All @@ -22,8 +22,8 @@
namespace gazebo
{

class ModelAttachmentPlugin : public WorldPlugin
{
class ModelAttachmentPlugin : public WorldPlugin
{
public:
ModelAttachmentPlugin();

Expand All @@ -35,20 +35,20 @@ class ModelAttachmentPlugin : public WorldPlugin
private:
physics::WorldPtr world_;

bool attachCallback(const std::shared_ptr<gazebo_model_attachment_plugin::srv::Attach::Request> req,
std::shared_ptr<gazebo_model_attachment_plugin::srv::Attach::Response> res);
bool detachCallback(const std::shared_ptr<gazebo_model_attachment_plugin::srv::Detach::Request> req,
std::shared_ptr<gazebo_model_attachment_plugin::srv::Detach::Response> res);
bool attachCallback(const std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Attach::Request> req,
std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Attach::Response> res);
bool detachCallback(const std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Detach::Request> req,
std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Detach::Response> res);

void attach(const std::string& joint_name, physics::ModelPtr m1, physics::ModelPtr m2, physics::LinkPtr l1,
void attach(const std::string &joint_name, physics::ModelPtr m1, physics::ModelPtr m2, physics::LinkPtr l1,
physics::LinkPtr l2);
void detach(const std::string& joint_name, physics::ModelPtr m1, physics::ModelPtr m2);
void detach(const std::string &joint_name, physics::ModelPtr m1, physics::ModelPtr m2);

gazebo_ros::Node::SharedPtr node_;

rclcpp::Service<gazebo_model_attachment_plugin::srv::Attach>::SharedPtr attach_srv_;
rclcpp::Service<gazebo_model_attachment_plugin::srv::Detach>::SharedPtr detach_srv_;
};
} // namespace gazebo
rclcpp::Service<gazebo_model_attachment_plugin_msgs::srv::Attach>::SharedPtr attach_srv_;
rclcpp::Service<gazebo_model_attachment_plugin_msgs::srv::Detach>::SharedPtr detach_srv_;
};
} // namespace gazebo

#endif
5 changes: 3 additions & 2 deletions package.xml → gazebo_model_attachment_plugin/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<depend>gazebo_ros</depend>
<depend>rclcpp</depend>
<depend>std_msgs</depend>
<depend>gazebo_model_attachment_plugin_msgs</depend>

<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
Expand All @@ -29,6 +30,6 @@

<export>
<build_type>ament_cmake</build_type>
<gazebo_ros plugin_path="${prefix}/lib" gazebo_media_path="${prefix}"/>
<gazebo_ros plugin_path="${prefix}/lib" gazebo_media_path="${prefix}" />
</export>
</package>
</package>
File renamed without changes.
244 changes: 244 additions & 0 deletions gazebo_model_attachment_plugin/src/gazebo_model_attachment_plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
// Copyright 2018 Boeing
#include <gazebo_model_attachment_plugin/gazebo_model_attachment_plugin.h>

#include <gazebo/physics/World.hh>
#include <sdf/sdf.hh>
#include <string>
#include <vector>

#include "gazebo_ros/node.hpp"

namespace gazebo
{

ModelAttachmentPlugin::ModelAttachmentPlugin()
{
}

ModelAttachmentPlugin::~ModelAttachmentPlugin()
{
}

// cppcheck-suppress unusedFunction
void ModelAttachmentPlugin::Load(physics::WorldPtr world, sdf::ElementPtr sdf)
{
world_ = world;

node_ = gazebo_ros::Node::Get(sdf);

attach_srv_ = node_->create_service<gazebo_model_attachment_plugin_msgs::srv::Attach>(
"/gazebo/attach",
std::bind(&ModelAttachmentPlugin::attachCallback, this, std::placeholders::_1, std::placeholders::_2));
detach_srv_ = node_->create_service<gazebo_model_attachment_plugin_msgs::srv::Detach>(
"/gazebo/detach",
std::bind(&ModelAttachmentPlugin::detachCallback, this, std::placeholders::_1, std::placeholders::_2));
}

bool ModelAttachmentPlugin::attachCallback(
const std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Attach::Request> req,
std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Attach::Response> res)
{
RCLCPP_INFO_STREAM(rclcpp::get_logger("rclcpp"),
"Received request to attach model: '" << req->model_name_1 << "' to '" << req->model_name_2);

// block any other physics pose updates
boost::recursive_mutex::scoped_lock plock(*(world_->Physics()->GetPhysicsUpdateMutex()));

const std::string &model_1_name = req->model_name_1;
const std::string &model_2_name = req->model_name_2;
const gazebo::physics::Model_V models = world_->Models();

auto m1 =
std::find_if(models.begin(), models.end(),
[&model_1_name](const gazebo::physics::ModelPtr &ptr)
{ return ptr->GetName() == model_1_name; });
if (m1 == models.end())
{
const std::string error_msg = "Could not find model " + req->model_name_1;
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

auto m2 =
std::find_if(models.begin(), models.end(),
[&model_2_name](const gazebo::physics::ModelPtr &ptr)
{ return ptr->GetName() == model_2_name; });
if (m2 == models.end())
{
const std::string error_msg = "Could not find model " + req->model_name_2;
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

physics::LinkPtr l1 = (*m1)->GetLink(req->link_name_1);
if (l1 == nullptr)
{
const std::string error_msg = "Could not find link " + req->link_name_1 + " on model " + req->model_name_1;
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

physics::LinkPtr l2 = (*m2)->GetLink(req->link_name_2);
if (l2 == nullptr)
{
const std::string error_msg = "Could not find link " + req->link_name_2 + " on model " + req->model_name_2;
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

try
{
attach(req->joint_name, *m1, *m2, l1, l2);
}
catch (const std::exception &e)
{
const std::string error_msg = "Failed to detach: " + std::string(e.what());
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

res->success = true;
return true;
}

// cppcheck-suppress constParameterCallback
bool ModelAttachmentPlugin::detachCallback(
const std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Detach::Request> req,
std::shared_ptr<gazebo_model_attachment_plugin_msgs::srv::Detach::Response> res)
{
RCLCPP_INFO_STREAM(rclcpp::get_logger("rclcpp"),
"Received request to detach model: '" << req->model_name_1 << "' from '" << req->model_name_2);

const std::string &model_1_name = req->model_name_1;
const std::string &model_2_name = req->model_name_2;
const gazebo::physics::Model_V models = world_->Models();

auto m1 =
std::find_if(models.begin(), models.end(),
[&model_1_name](const gazebo::physics::ModelPtr &ptr)
{ return ptr->GetName() == model_1_name; });
if (m1 == models.end())
{
const std::string error_msg = "Could not find model " + req->model_name_1;
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

auto m2 =
std::find_if(models.begin(), models.end(),
[&model_2_name](const gazebo::physics::ModelPtr &ptr)
{ return ptr->GetName() == model_2_name; });
if (m2 == models.end())
{
const std::string error_msg = "Could not find model " + req->model_name_2;
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

try
{
detach(req->joint_name, *m1, *m2);
}
catch (const std::exception &e)
{
const std::string error_msg = "Failed to detach: " + std::string(e.what());
RCLCPP_FATAL_STREAM(rclcpp::get_logger("rclcpp"), error_msg);
res->message = error_msg;
res->success = false;
return true;
}

res->success = true;
return true;
}

void ModelAttachmentPlugin::attach(const std::string &joint_name, physics::ModelPtr m1, physics::ModelPtr m2,
physics::LinkPtr l1, physics::LinkPtr l2)
{
if (m1 == nullptr)
throw std::runtime_error("Model 1 is null");

if (m2 == nullptr)
throw std::runtime_error("Model 2 is null");

if (l1 == nullptr)
throw std::runtime_error("Link 1 is null");

if (l2 == nullptr)
throw std::runtime_error("Link 2 is null");

ignition::math::Pose3d m1wp = m1->WorldPose();
ignition::math::Pose3d l1rl = l1->RelativePose();
ignition::math::Pose3d l2rl = l2->RelativePose();
ignition::math::Pose3d p = (m1wp * l1rl * l2rl.Inverse());
const bool is_paused = world_->IsPaused();
world_->SetPaused(true);
m2->SetWorldPose(p);

physics::JointPtr joint = m1->CreateJoint(joint_name, "fixed", l1, l2);

if (joint == nullptr)
throw std::runtime_error("CreateJoint returned nullptr");

m1->AddChild(m2);
world_->SetPaused(is_paused);
}

void ModelAttachmentPlugin::detach(const std::string &joint_name, physics::ModelPtr m1, physics::ModelPtr m2)
{
if (m1 == nullptr)
throw std::runtime_error("Model 1 is null");

if (m2 == nullptr)
throw std::runtime_error("Model 2 is null");

physics::JointPtr joint = m1->GetJoint(joint_name);
if (joint == nullptr)
throw std::runtime_error("No joint on model " + m1->GetName() + " by name " + joint_name);

const bool is_paused = world_->IsPaused();
world_->SetPaused(true);
bool success = m1->RemoveJoint(joint_name);

if (!success)
throw std::runtime_error("Unable to remove joint from model");

m2->SetParent(m1->GetWorld()->ModelByName("default"));

// We need to flush the children vector of the parent
// Calling m1->RemoveChild(boost::dynamic_pointer_cast<physics::Entity>(m2)); will also destroy the child
physics::Base_V temp_child_objects;
unsigned int children_count = m1->GetChildCount();
for (unsigned int i = 0; i < children_count; i++)
{
if (m1->GetChild(i) != m2)
temp_child_objects.push_back(m1->GetChild(i));
}

m1->RemoveChildren();

for (const auto &obj : temp_child_objects)
{
m1->AddChild(obj);
}
world_->SetPaused(is_paused);

return;
}

GZ_REGISTER_WORLD_PLUGIN(ModelAttachmentPlugin)
} // namespace gazebo
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import logging
import rclpy

from gazebo_model_attachment_plugin.srv import Attach
from gazebo_model_attachment_plugin.srv import Detach
from gazebo_model_attachment_plugin_msgs.srv import Attach
from gazebo_model_attachment_plugin_msgs.srv import Detach

logger = logging.getLogger(__name__)

Expand Down
File renamed without changes.
Loading

0 comments on commit b5d01c2

Please sign in to comment.