4 #include <gazebo/physics/World.hh>
32 gazebo_model_attachment_plugin::Attach::Response& res)
34 ROS_INFO_STREAM(
"Received request to attach model: '" << req.model_name_1 <<
"' to '" << req.model_name_2);
37 boost::recursive_mutex::scoped_lock plock(*(
world_->Physics()->GetPhysicsUpdateMutex()));
39 const std::string& model_1_name = req.model_name_1;
40 const std::string& model_2_name = req.model_name_2;
41 const gazebo::physics::Model_V models =
world_->Models();
43 auto m1 = std::find_if(models.begin(), models.end(), [&model_1_name](
const gazebo::physics::ModelPtr& ptr) {
44 return ptr->GetName() == model_1_name;
46 if (m1 == models.end())
48 const std::string error_msg =
"Could not find model " + req.model_name_1;
50 res.message = error_msg;
55 auto m2 = std::find_if(models.begin(), models.end(), [&model_2_name](
const gazebo::physics::ModelPtr& ptr) {
56 return ptr->GetName() == model_2_name;
58 if (m2 == models.end())
60 const std::string error_msg =
"Could not find model " + req.model_name_2;
62 res.message = error_msg;
67 physics::LinkPtr l1 = (*m1)->GetLink(req.link_name_1);
70 const std::string error_msg =
"Could not find link " + req.link_name_1 +
" on model " + req.model_name_1;
72 res.message = error_msg;
77 physics::LinkPtr l2 = (*m2)->GetLink(req.link_name_2);
80 const std::string error_msg =
"Could not find link " + req.link_name_2 +
" on model " + req.model_name_2;
82 res.message = error_msg;
89 attach(req.joint_name, *m1, *m2, l1, l2);
91 catch (
const std::exception& e)
93 const std::string error_msg =
"Failed to detach: " + std::string(e.what());
95 res.message = error_msg;
106 gazebo_model_attachment_plugin::Detach::Response& res)
108 ROS_INFO_STREAM(
"Received request to detach model: '" << req.model_name_1 <<
"' from '" << req.model_name_2);
110 const std::string& model_1_name = req.model_name_1;
111 const std::string& model_2_name = req.model_name_2;
112 const gazebo::physics::Model_V models =
world_->Models();
114 auto m1 = std::find_if(models.begin(), models.end(), [&model_1_name](
const gazebo::physics::ModelPtr& ptr) {
115 return ptr->GetName() == model_1_name;
117 if (m1 == models.end())
119 const std::string error_msg =
"Could not find model " + req.model_name_1;
121 res.message = error_msg;
126 auto m2 = std::find_if(models.begin(), models.end(), [&model_2_name](
const gazebo::physics::ModelPtr& ptr) {
127 return ptr->GetName() == model_2_name;
129 if (m2 == models.end())
131 const std::string error_msg =
"Could not find model " + req.model_name_2;
133 res.message = error_msg;
140 detach(req.joint_name, *m1, *m2);
142 catch (
const std::exception& e)
144 const std::string error_msg =
"Failed to detach: " + std::string(e.what());
146 res.message = error_msg;
156 physics::LinkPtr l1, physics::LinkPtr l2)
159 throw std::runtime_error(
"Model 1 is null");
162 throw std::runtime_error(
"Model 2 is null");
165 throw std::runtime_error(
"Link 1 is null");
168 throw std::runtime_error(
"Link 2 is null");
170 ignition::math::Pose3d m1wp = m1->WorldPose();
171 ignition::math::Pose3d l1rl = l1->RelativePose();
172 ignition::math::Pose3d l2rl = l2->RelativePose();
173 ignition::math::Pose3d p = (m1wp * l1rl * l2rl.Inverse());
177 physics::JointPtr joint = m1->CreateJoint(joint_name,
"fixed", l1, l2);
179 if (joint ==
nullptr)
180 throw std::runtime_error(
"CreateJoint returned nullptr");
188 throw std::runtime_error(
"Model 1 is null");
191 throw std::runtime_error(
"Model 2 is null");
193 physics::JointPtr joint = m1->GetJoint(joint_name);
194 if (joint ==
nullptr)
195 throw std::runtime_error(
"No joint on model " + m1->GetName() +
" by name " + joint_name);
197 bool success = m1->RemoveJoint(joint_name);
200 throw std::runtime_error(
"Unable to remove joint from model");
202 m2->SetParent(m1->GetWorld()->ModelByName(
"default"));
206 physics::Base_V temp_child_objects;
207 unsigned int children_count = m1->GetChildCount();
208 for (
unsigned int i = 0; i < children_count; i++)
210 if (m1->GetChild(i) != m2)
211 temp_child_objects.push_back(m1->GetChild(i));
214 m1->RemoveChildren();
216 for (
const auto& obj : temp_child_objects)