gazebo_model_attachment_plugin.cpp
Go to the documentation of this file.
1 // Copyright 2018 Boeing
3 
4 #include <gazebo/physics/World.hh>
5 #include <sdf/sdf.hh>
6 #include <string>
7 #include <vector>
8 
9 namespace gazebo
10 {
11 
13 {
14 }
15 
17 {
18 }
19 
20 // cppcheck-suppress unusedFunction
21 void ModelAttachmentPlugin::Load(physics::WorldPtr world, sdf::ElementPtr)
22 {
23  world_ = world;
24 
25  nh_ = ros::NodeHandle("~");
26 
29 }
30 
31 bool ModelAttachmentPlugin::attachCallback(gazebo_model_attachment_plugin::Attach::Request& req,
32  gazebo_model_attachment_plugin::Attach::Response& res)
33 {
34  ROS_INFO_STREAM("Received request to attach model: '" << req.model_name_1 << "' to '" << req.model_name_2);
35 
36  // block any other physics pose updates
37  boost::recursive_mutex::scoped_lock plock(*(world_->Physics()->GetPhysicsUpdateMutex()));
38 
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();
42 
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;
45  });
46  if (m1 == models.end())
47  {
48  const std::string error_msg = "Could not find model " + req.model_name_1;
49  ROS_ERROR_STREAM(error_msg);
50  res.message = error_msg;
51  res.success = false;
52  return true;
53  }
54 
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;
57  });
58  if (m2 == models.end())
59  {
60  const std::string error_msg = "Could not find model " + req.model_name_2;
61  ROS_ERROR_STREAM(error_msg);
62  res.message = error_msg;
63  res.success = false;
64  return true;
65  }
66 
67  physics::LinkPtr l1 = (*m1)->GetLink(req.link_name_1);
68  if (l1 == nullptr)
69  {
70  const std::string error_msg = "Could not find link " + req.link_name_1 + " on model " + req.model_name_1;
71  ROS_ERROR_STREAM(error_msg);
72  res.message = error_msg;
73  res.success = false;
74  return true;
75  }
76 
77  physics::LinkPtr l2 = (*m2)->GetLink(req.link_name_2);
78  if (l2 == nullptr)
79  {
80  const std::string error_msg = "Could not find link " + req.link_name_2 + " on model " + req.model_name_2;
81  ROS_ERROR_STREAM(error_msg);
82  res.message = error_msg;
83  res.success = false;
84  return true;
85  }
86 
87  try
88  {
89  attach(req.joint_name, *m1, *m2, l1, l2);
90  }
91  catch (const std::exception& e)
92  {
93  const std::string error_msg = "Failed to detach: " + std::string(e.what());
94  ROS_ERROR_STREAM(error_msg);
95  res.message = error_msg;
96  res.success = false;
97  return true;
98  }
99 
100  res.success = true;
101  return true;
102 }
103 
104 // cppcheck-suppress constParameterCallback
105 bool ModelAttachmentPlugin::detachCallback(gazebo_model_attachment_plugin::Detach::Request& req,
106  gazebo_model_attachment_plugin::Detach::Response& res)
107 {
108  ROS_INFO_STREAM("Received request to detach model: '" << req.model_name_1 << "' from '" << req.model_name_2);
109 
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();
113 
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;
116  });
117  if (m1 == models.end())
118  {
119  const std::string error_msg = "Could not find model " + req.model_name_1;
120  ROS_ERROR_STREAM(error_msg);
121  res.message = error_msg;
122  res.success = false;
123  return true;
124  }
125 
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;
128  });
129  if (m2 == models.end())
130  {
131  const std::string error_msg = "Could not find model " + req.model_name_2;
132  ROS_ERROR_STREAM(error_msg);
133  res.message = error_msg;
134  res.success = false;
135  return true;
136  }
137 
138  try
139  {
140  detach(req.joint_name, *m1, *m2);
141  }
142  catch (const std::exception& e)
143  {
144  const std::string error_msg = "Failed to detach: " + std::string(e.what());
145  ROS_ERROR_STREAM(error_msg);
146  res.message = error_msg;
147  res.success = false;
148  return true;
149  }
150 
151  res.success = true;
152  return true;
153 }
154 
155 void ModelAttachmentPlugin::attach(const std::string& joint_name, physics::ModelPtr m1, physics::ModelPtr m2,
156  physics::LinkPtr l1, physics::LinkPtr l2)
157 {
158  if (m1 == nullptr)
159  throw std::runtime_error("Model 1 is null");
160 
161  if (m2 == nullptr)
162  throw std::runtime_error("Model 2 is null");
163 
164  if (l1 == nullptr)
165  throw std::runtime_error("Link 1 is null");
166 
167  if (l2 == nullptr)
168  throw std::runtime_error("Link 2 is null");
169 
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());
174 
175  m2->SetWorldPose(p);
176 
177  physics::JointPtr joint = m1->CreateJoint(joint_name, "fixed", l1, l2);
178 
179  if (joint == nullptr)
180  throw std::runtime_error("CreateJoint returned nullptr");
181 
182  m1->AddChild(m2);
183 }
184 
185 void ModelAttachmentPlugin::detach(const std::string& joint_name, physics::ModelPtr m1, physics::ModelPtr m2)
186 {
187  if (m1 == nullptr)
188  throw std::runtime_error("Model 1 is null");
189 
190  if (m2 == nullptr)
191  throw std::runtime_error("Model 2 is null");
192 
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);
196 
197  bool success = m1->RemoveJoint(joint_name);
198 
199  if (!success)
200  throw std::runtime_error("Unable to remove joint from model");
201 
202  m2->SetParent(m1->GetWorld()->ModelByName("default"));
203 
204  // We need to flush the children vector of the parent
205  // Calling m1->RemoveChild(boost::dynamic_pointer_cast<physics::Entity>(m2)); will also destroy the child
206  physics::Base_V temp_child_objects;
207  unsigned int children_count = m1->GetChildCount();
208  for (unsigned int i = 0; i < children_count; i++)
209  {
210  if (m1->GetChild(i) != m2)
211  temp_child_objects.push_back(m1->GetChild(i));
212  }
213 
214  m1->RemoveChildren();
215 
216  for (const auto& obj : temp_child_objects)
217  {
218  m1->AddChild(obj);
219  }
220 
221  return;
222 }
223 
224 GZ_REGISTER_WORLD_PLUGIN(ModelAttachmentPlugin)
225 } // namespace gazebo
gazebo::ModelAttachmentPlugin::attach_srv_
ros::ServiceServer attach_srv_
Definition: gazebo_model_attachment_plugin.h:46
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
gazebo
gazebo::ModelAttachmentPlugin::detach_srv_
ros::ServiceServer detach_srv_
Definition: gazebo_model_attachment_plugin.h:47
ros::NodeHandle::advertiseService
ServiceServer advertiseService(AdvertiseServiceOptions &ops)
gazebo::ModelAttachmentPlugin::detachCallback
bool detachCallback(gazebo_model_attachment_plugin::Detach::Request &req, gazebo_model_attachment_plugin::Detach::Response &res)
Definition: gazebo_model_attachment_plugin.cpp:105
gazebo::ModelAttachmentPlugin::attachCallback
bool attachCallback(gazebo_model_attachment_plugin::Attach::Request &req, gazebo_model_attachment_plugin::Attach::Response &res)
Definition: gazebo_model_attachment_plugin.cpp:31
gazebo::ModelAttachmentPlugin::detach
void detach(const std::string &joint_name, physics::ModelPtr m1, physics::ModelPtr m2)
Definition: gazebo_model_attachment_plugin.cpp:185
gazebo::ModelAttachmentPlugin::~ModelAttachmentPlugin
virtual ~ModelAttachmentPlugin()
Definition: gazebo_model_attachment_plugin.cpp:16
gazebo::ModelAttachmentPlugin
Definition: gazebo_model_attachment_plugin.h:23
gazebo::ModelAttachmentPlugin::world_
physics::WorldPtr world_
Definition: gazebo_model_attachment_plugin.h:34
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
gazebo::ModelAttachmentPlugin::Load
void Load(physics::WorldPtr world, sdf::ElementPtr sdf)
Definition: gazebo_model_attachment_plugin.cpp:21
gazebo::ModelAttachmentPlugin::ModelAttachmentPlugin
ModelAttachmentPlugin()
Definition: gazebo_model_attachment_plugin.cpp:12
gazebo_model_attachment_plugin.h
gazebo::ModelAttachmentPlugin::nh_
ros::NodeHandle nh_
Definition: gazebo_model_attachment_plugin.h:45
gazebo::ModelAttachmentPlugin::attach
void attach(const std::string &joint_name, physics::ModelPtr m1, physics::ModelPtr m2, physics::LinkPtr l1, physics::LinkPtr l2)
Definition: gazebo_model_attachment_plugin.cpp:155
ros::NodeHandle


boeing_gazebo_model_attachment_plugin
Author(s): Boeing
autogenerated on Fri Dec 15 2023 03:43:22