parent_and_child_interactive_marker_server.cpp
Go to the documentation of this file.
2 
4 {
5  ParentAndChildInteractiveMarkerServer::ParentAndChildInteractiveMarkerServer(const std::string &topic_ns, const std::string &server_id, bool spin_thread) : InteractiveMarkerServer(topic_ns, server_id, spin_thread)
6  {
7  topic_server_name_ = topic_ns;
8  std::string get_marker_pose_service_name = topic_ns + "/get_marker_pose";
9  std::string set_parent_service_name = topic_ns + "/set_parent_marker";
10  std::string remove_parent_service_name = topic_ns + "/remove_parent_marker";
14  }
15  bool ParentAndChildInteractiveMarkerServer::setParentService(jsk_interactive_marker::SetParentMarker::Request &req, jsk_interactive_marker::SetParentMarker::Response &res)
16  {
17  geometry_msgs::PoseStamped child_pose_stamped;
18  // get current pose stamped
19  getMarkerPose(req.child_marker_name, child_pose_stamped);
20  if (req.parent_topic_name == std::string("") || topic_server_name_ == req.parent_topic_name) // self association
21  {
22  if (!registerAssociationItself(req.parent_marker_name, topic_server_name_, req.child_marker_name, child_pose_stamped))
23  return false;
24  }
25  else{ // refer to different server
26  if (registerAssociationWithOtherNode(req.parent_marker_name, req.parent_topic_name, req.child_marker_name, child_pose_stamped))
27  {
28 
29  if (parent_subscriber_nums_.find(req.parent_topic_name) == parent_subscriber_nums_.end() || parent_subscriber_nums_[req.parent_topic_name] == 0 )
30  {
31  // register subscriber
32  parent_subscriber_nums_[req.parent_topic_name] = 1;
33  parent_update_subscribers_[req.parent_topic_name] = n_.subscribe<visualization_msgs::InteractiveMarkerUpdate>(req.parent_topic_name + "/update", 1, boost::bind(&ParentAndChildInteractiveMarkerServer::parentUpdateCb, this, _1, req.parent_topic_name));
34  parent_feedback_subscribers_[req.parent_topic_name] = n_.subscribe<visualization_msgs::InteractiveMarkerFeedback>(req.parent_topic_name + "/feedback", 1, boost::bind(&ParentAndChildInteractiveMarkerServer::parentFeedbackCb, this, _1, req.parent_topic_name));
35  }
36  else
37  {
38  parent_subscriber_nums_[req.parent_topic_name] += 1;
39  }
40  }
41  else
42  {
43  return false;
44  }
45  }
46  if (! (callback_map_.find(req.child_marker_name)!=callback_map_.end()))
47  {
48  setCallback(req.child_marker_name, NULL, DEFAULT_FEEDBACK_CB);
49  }
50  if ((req.parent_topic_name == std::string("") || topic_server_name_ == req.parent_topic_name) && ! (callback_map_.find(req.parent_marker_name)!=callback_map_.end()))
51  {
52  setCallback(req.parent_marker_name, NULL, DEFAULT_FEEDBACK_CB);
53  }
54  return true;
55  }
56  bool ParentAndChildInteractiveMarkerServer::registerAssociationItself(std::string parent_marker_name, std::string parent_topic_name, std::string child_marker_name, geometry_msgs::PoseStamped child_pose_stamped)
57  {
58  geometry_msgs::PoseStamped parent_pose_stamped;
59  getMarkerPose(parent_marker_name, parent_pose_stamped);
60  return registerAssociation(parent_marker_name, parent_topic_name, child_marker_name, child_pose_stamped, parent_pose_stamped);
61  }
62  bool ParentAndChildInteractiveMarkerServer::registerAssociationWithOtherNode(std::string parent_marker_name, std::string parent_topic_name, std::string child_marker_name, geometry_msgs::PoseStamped child_pose_stamped)
63  {
64  geometry_msgs::PoseStamped parent_pose_stamped;
65  ros::ServiceClient client = n_.serviceClient<jsk_interactive_marker::GetTransformableMarkerPose>(parent_topic_name + "/get_marker_pose");
66  jsk_interactive_marker::GetTransformableMarkerPose srv;
67  srv.request.target_name = parent_marker_name;
68  if (!client.call(srv))
69  {
70  return false;
71  }
72  parent_pose_stamped = srv.response.pose_stamped;
73  return registerAssociation(parent_marker_name, parent_topic_name, child_marker_name, child_pose_stamped, parent_pose_stamped);
74  }
75  bool ParentAndChildInteractiveMarkerServer::registerAssociation(std::string parent_marker_name, std::string parent_topic_name, std::string child_marker_name, geometry_msgs::PoseStamped child_pose_stamped, geometry_msgs::PoseStamped parent_pose_stamped)
76  {
77  geometry_msgs::PoseStamped parent_pose_stamped_transed;
78  if (tf_listener_.waitForTransform(child_pose_stamped.header.frame_id,
79  parent_pose_stamped.header.frame_id, parent_pose_stamped.header.stamp, ros::Duration(1.0)))
80  {
81  tf_listener_.transformPose(child_pose_stamped.header.frame_id, parent_pose_stamped, parent_pose_stamped_transed);
82  }
83  else
84  {
85  return false;
86  }
87  Eigen::Affine3d parent_pose_eigened, child_pose_eigened;
88  tf::poseMsgToEigen(parent_pose_stamped_transed.pose, parent_pose_eigened);
89  tf::poseMsgToEigen(child_pose_stamped.pose, child_pose_eigened);
90  association_list_[child_marker_name] = jsk_interactive_marker::ParentMarkerInformation(parent_topic_name, parent_marker_name, parent_pose_eigened.inverse() * child_pose_eigened);
91  return true;
92  }
93 
94  bool ParentAndChildInteractiveMarkerServer::removeParentService(jsk_interactive_marker::RemoveParentMarker::Request &req, jsk_interactive_marker::RemoveParentMarker::Response &res)
95  {
96  return removeParent(req.child_marker_name);
97  }
98  bool ParentAndChildInteractiveMarkerServer::removeParent(std::string child_marker_name)
99  {
100  std::string parent_topic_name = association_list_[child_marker_name].parent_topic_name;
101  parent_subscriber_nums_[parent_topic_name] -= 1;
102  if (parent_subscriber_nums_[parent_topic_name] == 0)
103  {
104  parent_feedback_subscribers_[parent_topic_name].shutdown();
105  parent_update_subscribers_[parent_topic_name].shutdown();
106  }
107  setCallback(child_marker_name, NULL, 200);
108  association_list_.erase(child_marker_name);
109  return true;
110  }
111 
112  bool ParentAndChildInteractiveMarkerServer::getMarkerPoseService(jsk_interactive_marker::GetTransformableMarkerPose::Request &req, jsk_interactive_marker::GetTransformableMarkerPose::Response &res)
113  {
114  geometry_msgs::PoseStamped pose_stamped;
115  if (getMarkerPose(req.target_name, pose_stamped))
116  {
117  res.pose_stamped = pose_stamped;
118  }
119  else
120  return false;
121  }
122  bool ParentAndChildInteractiveMarkerServer::getMarkerPose(std::string target_name, geometry_msgs::PoseStamped &pose_stamped)
123  {
124  visualization_msgs::InteractiveMarker focus_marker;
125  if (get(target_name, focus_marker))
126  {
127  pose_stamped.pose = focus_marker.pose;
128  pose_stamped.header = focus_marker.header;
129  return true;
130  }
131  return false;
132  }
133  void ParentAndChildInteractiveMarkerServer::parentUpdateCb(const visualization_msgs::InteractiveMarkerUpdateConstPtr &update, std::string parent_topic_name)
134  {
135  // keep relative pose
136  bool need_apply_change = false;
137  std::map <std::string, ParentMarkerInformation>::iterator assoc_it = association_list_.begin();
138  while (assoc_it != association_list_.end()){
139  for (size_t i=0; i<update->markers.size(); i++){
140  if (assoc_it -> second.parent_topic_name == parent_topic_name && assoc_it -> second.parent_marker_name == update -> markers[i].name){
141  renewPoseWithParent(assoc_it, update -> markers[i].pose, update -> markers[i].header);
142  need_apply_change = true;
143  }
144  }
145  ++assoc_it;
146  }
147  // apply change
148  if (need_apply_change)
150  }
151  void ParentAndChildInteractiveMarkerServer::parentFeedbackCb(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, std::string parent_topic_name)
152  {
153  // keep relative pose
154  bool need_apply_change = false;
155  std::map <std::string, ParentMarkerInformation>::iterator assoc_it = association_list_.begin();
156  while (assoc_it != association_list_.end()){
157  if (assoc_it -> second.parent_topic_name == parent_topic_name && assoc_it -> second.parent_marker_name == feedback -> marker_name){
158  renewPoseWithParent(assoc_it, feedback -> pose, feedback -> header);
159  need_apply_change = true;
160  }
161  ++assoc_it;
162  }
163  // apply change
164  if (need_apply_change)
166  // apply change
167  }
168  void ParentAndChildInteractiveMarkerServer::renewPoseWithParent(std::map <std::string, ParentMarkerInformation>::iterator assoc_it, geometry_msgs::Pose parent_pose, std_msgs::Header parent_header)
169  {
170  Eigen::Affine3d parent_pose_eigened, child_new_pose_eigened;
171  tf::poseMsgToEigen(parent_pose, parent_pose_eigened);
172  child_new_pose_eigened = parent_pose_eigened * assoc_it -> second.relative_pose;
173  geometry_msgs::Pose child_new_pose;
174  tf::poseEigenToMsg(child_new_pose_eigened, child_new_pose);
175  setPose(assoc_it -> first, child_new_pose, parent_header);
176  }
177  void ParentAndChildInteractiveMarkerServer::selfFeedbackCb(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) // for updating relative pose with feedback
178  {
179  // keep relative pose
180  bool need_apply_change = false;
181  std::map <std::string, ParentMarkerInformation>::iterator assoc_it = association_list_.begin();
182  while (assoc_it != association_list_.end()){
183  if (assoc_it -> second.parent_topic_name == topic_server_name_ && assoc_it -> second.parent_marker_name == feedback -> marker_name){
184  renewPoseWithParent(assoc_it, feedback -> pose, feedback -> header);
185  need_apply_change = true;
186  }
187  ++assoc_it;
188  }
189  // apply change
190  if (need_apply_change){
192  }
193 
194  // check self parent
195  // renew all
196  // only when mouse is removed because it takes much cost for service call
197  if (feedback -> event_type != visualization_msgs::InteractiveMarkerFeedback::MOUSE_UP)
198  {
199  return;
200  }
201  // only changes feedback marker -> parent
202  geometry_msgs::PoseStamped feedback_pose_stamped;
203  feedback_pose_stamped.pose = feedback->pose;
204  feedback_pose_stamped.header = feedback->header;
205  assoc_it = association_list_.begin();
206  while (assoc_it != association_list_.end()){
207  if (assoc_it->first == feedback->marker_name){
208  if (topic_server_name_ == assoc_it->second.parent_topic_name)
209  {
210  registerAssociationItself(assoc_it->second.parent_marker_name, assoc_it->second.parent_topic_name, assoc_it->first, feedback_pose_stamped);
211  }
212  else
213  {
214  registerAssociationWithOtherNode(assoc_it->second.parent_marker_name, assoc_it->second.parent_topic_name, assoc_it->first, feedback_pose_stamped);
215  }
216  }
217  ++assoc_it;
218  }
219  }
220  void ParentAndChildInteractiveMarkerServer::applyChanges() // for updating relative pose with update
221  {
222  // keep relative pose
223  std::map <std::string, ParentMarkerInformation>::iterator assoc_it = association_list_.begin();
224  while (assoc_it != association_list_.end()){
225  if(assoc_it->second.parent_topic_name == topic_server_name_)
226  {
227  visualization_msgs::InteractiveMarker int_marker;
228  get(assoc_it->second.parent_marker_name, int_marker);
229  renewPoseWithParent(assoc_it, int_marker.pose, int_marker.header);
230  }
231  ++assoc_it;
232  }
233  // apply change
235  // check self parent
236  // renew all relative affine
237  assoc_it = association_list_.begin();
238  while (assoc_it != association_list_.end()){
239  if (topic_server_name_ == assoc_it->second.parent_topic_name)
240  {
241  geometry_msgs::PoseStamped feedback_pose_stamped;
242  visualization_msgs::InteractiveMarker int_marker;
243  get(assoc_it->first, int_marker);
244  feedback_pose_stamped.pose = int_marker.pose; feedback_pose_stamped.header = int_marker.header;
245  registerAssociationItself(assoc_it->second.parent_marker_name, assoc_it->second.parent_topic_name, assoc_it->first, feedback_pose_stamped);
246  }
247  ++assoc_it;
248  }
249  }
250  bool ParentAndChildInteractiveMarkerServer::setCallback(const std::string &name, FeedbackCallback feedback_cb, uint8_t feedback_type)
251  {
252  // synthesize cbs
253  callback_map_[name] = std::make_shared<FeedbackSynthesizer> (boost::bind(&ParentAndChildInteractiveMarkerServer::selfFeedbackCb, this, _1), feedback_cb);
255  }
256  void ParentAndChildInteractiveMarkerServer::insert(const visualization_msgs::InteractiveMarker &int_marker)
257  {
258  callback_map_.erase(int_marker.name);
259  removeParent(int_marker.name);
261  }
262  void ParentAndChildInteractiveMarkerServer::insert(const visualization_msgs::InteractiveMarker &int_marker, FeedbackCallback feedback_cb, uint8_t feedback_type)
263  {
264  insert(int_marker);
265  // synthesize cbs
266  ParentAndChildInteractiveMarkerServer::setCallback(int_marker.name, feedback_cb, feedback_type);
267  }
268  bool ParentAndChildInteractiveMarkerServer::erase(const std::string &name)
269  {
270  // erase cb
271  callback_map_.erase(name);
272  removeParent(name);
274  }
275 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
bool registerAssociationItself(std::string parent_marker_name, std::string parent_topic_name, std::string child_marker_name, geometry_msgs::PoseStamped child_pose_stamped)
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void poseMsgToEigen(const geometry_msgs::Pose &m, Eigen::Affine3d &e)
void call_func(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
ParentAndChildInteractiveMarkerServer(const std::string &topic_ns, const std::string &server_id="", bool spin_thread=false)
void renewPoseWithParent(std::map< std::string, ParentMarkerInformation >::iterator assoc_it_, geometry_msgs::Pose parent_pose, std_msgs::Header parent_header)
bool call(MReq &req, MRes &res)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
pose
boost::function< void(const FeedbackConstPtr &) > FeedbackCallback
bool waitForTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01), std::string *error_msg=NULL) const
void insert(const visualization_msgs::InteractiveMarker &int_marker)
void selfFeedbackCb(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
bool registerAssociationWithOtherNode(std::string parent_marker_name, std::string parent_topic_name, std::string child_marker_name, geometry_msgs::PoseStamped child_pose_stamped)
header
srv
bool getMarkerPoseService(jsk_interactive_marker::GetTransformableMarkerPose::Request &req, jsk_interactive_marker::GetTransformableMarkerPose::Response &res)
INTERACTIVE_MARKERS_PUBLIC void insert(const visualization_msgs::InteractiveMarker &int_marker)
void transformPose(const std::string &target_frame, const geometry_msgs::PoseStamped &stamped_in, geometry_msgs::PoseStamped &stamped_out) const
INTERACTIVE_MARKERS_PUBLIC void applyChanges()
INTERACTIVE_MARKERS_PUBLIC bool setCallback(const std::string &name, FeedbackCallback feedback_cb, uint8_t feedback_type=DEFAULT_FEEDBACK_CB)
std::map< std::string, std::shared_ptr< FeedbackSynthesizer > > callback_map_
#define NULL
bool removeParentService(jsk_interactive_marker::RemoveParentMarker::Request &req, jsk_interactive_marker::RemoveParentMarker::Response &res)
INTERACTIVE_MARKERS_PUBLIC bool setPose(const std::string &name, const geometry_msgs::Pose &pose, const std_msgs::Header &header=std_msgs::Header())
void parentUpdateCb(const visualization_msgs::InteractiveMarkerUpdateConstPtr &update, std::string parent_topic_name)
bool registerAssociation(std::string parent_marker_name, std::string parent_topic_name, std::string child_marker_name, geometry_msgs::PoseStamped child_pose_stamped, geometry_msgs::PoseStamped parent_pose_stamped)
bool setParentService(jsk_interactive_marker::SetParentMarker::Request &req, jsk_interactive_marker::SetParentMarker::Response &res)
bool getMarkerPose(std::string target_name, geometry_msgs::PoseStamped &pose_stamped)
INTERACTIVE_MARKERS_PUBLIC bool erase(const std::string &name)
bool setCallback(const std::string &name, FeedbackCallback feedback_cb, uint8_t feedback_type=DEFAULT_FEEDBACK_CB)
void parentFeedbackCb(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback, std::string parent_topic_name)


jsk_interactive_marker
Author(s): furuta
autogenerated on Sat Mar 20 2021 03:03:33