rest_hand_eye_calibration_client.cc
Go to the documentation of this file.
2 
3 #include <ifaddrs.h>
4 #include <arpa/inet.h>
5 #include <unistd.h>
6 
7 #include "json.hpp"
8 #include <cpr/cpr.h>
9 
10 using namespace std;
12 
13 
14 namespace //anonymous
15 {
16 
17 string toString(cpr::Response resp)
18 {
19  stringstream s;
20  s << "status code: " << resp.status_code << endl
21  << "url: " << resp.url << endl
22  << "text: " << resp.text << endl
23  << "error: " << resp.error.message;
24  return s.str();
25 }
26 
27 void handleCPRResponse(cpr::Response r)
28 {
29  if (r.status_code != 200)
30  {
31  throw runtime_error(toString(r));
32  }
33 }
34 
35 }//anonymous ns
36 
37 
39  : nh_(nh), host_(host),
40  servicesUrl_("http://" + host + "/api/v1/nodes/rc_hand_eye_calibration/services/"),
41  paramsUrl_("http://" + host + "/api/v1/nodes/rc_hand_eye_calibration/parameters")
42 {
43  timeoutCurl_ = 2000;
46 }
47 
48 
49 bool CalibrationWrapper::saveSrv(std_srvs::TriggerRequest &,
50  std_srvs::TriggerResponse &response)
51 {
52  cpr::Url url = cpr::Url{ servicesUrl_ + "save_calibration"};
53  auto rest_resp = cpr::Put(url, cpr::Timeout{ timeoutCurl_ });
54  handleCPRResponse(rest_resp);
55 
56  auto json_resp = json::parse(rest_resp.text)["response"];
57  response.success = (bool) json_resp["success"];
58  response.message = json_resp["message"];
59  return true;
60 
61  return true;
62 }
63 
64 
65 bool CalibrationWrapper::resetSrv(std_srvs::TriggerRequest &,
66  std_srvs::TriggerResponse &response)
67 {
68  cpr::Url url = cpr::Url{ servicesUrl_ + "reset_calibration"};
69  auto rest_resp = cpr::Put(url, cpr::Timeout{ timeoutCurl_ });
70  handleCPRResponse(rest_resp);
71 
72  auto json_resp = json::parse(rest_resp.text)["response"];
73  response.success = (bool) json_resp["success"];
74  response.message = json_resp["message"];
75  return true;
76 }
77 
78 
79 bool CalibrationWrapper::removeSrv(std_srvs::TriggerRequest &,
80  std_srvs::TriggerResponse &response)
81 {
82  cpr::Url url = cpr::Url{ servicesUrl_ + "remove_calibration"};
83  auto rest_resp = cpr::Put(url, cpr::Timeout{ timeoutCurl_ });
84  handleCPRResponse(rest_resp);
85 
86  auto json_resp = json::parse(rest_resp.text)["response"];
87  response.success = (bool) json_resp["success"];
88  response.message = json_resp["message"];
89  return true;
90 }
91 
92 
93 bool CalibrationWrapper::setSlotSrv(rc_hand_eye_calibration_client::SetCalibrationPoseRequest &request,
94  rc_hand_eye_calibration_client::SetCalibrationPoseResponse &response)
95 {
96  // convert ros pose to json obj
97  json js_pos, js_ori, js_pose;
98  js_pos["x"] = request.pose.position.x;
99  js_pos["y"] = request.pose.position.y;
100  js_pos["z"] = request.pose.position.z;
101  js_ori["x"] = request.pose.orientation.x;
102  js_ori["y"] = request.pose.orientation.y;
103  js_ori["z"] = request.pose.orientation.z;
104  js_ori["w"] = request.pose.orientation.w;
105  js_pose["position"] = js_pos;
106  js_pose["orientation"] = js_ori;
107 
108  // fill service args
109  json js_args;
110  js_args["args"]["pose"] = js_pose;
111  js_args["args"]["slot"] = request.slot;
112 
113  // do service request
114  cpr::Url url = cpr::Url{ servicesUrl_ + "set_pose" };
115  auto rest_resp = cpr::Put(url, cpr::Timeout{ timeoutCurl_ }, cpr::Body{ js_args.dump() },
116  cpr::Header{ { "Content-Type", "application/json" } });
117  handleCPRResponse(rest_resp);
118 
119  // parse json response into ros message
120  auto json_resp = json::parse(rest_resp.text)["response"];
121  response.success = (bool) json_resp["success"];
122  response.status = json_resp["status"];
123  response.message = json_resp["message"];
124  return true;
125 }
126 
127 
128 bool CalibrationWrapper::calibSrv(rc_hand_eye_calibration_client::CalibrationRequest &,
129  rc_hand_eye_calibration_client::CalibrationResponse &response)
130 {
131  // do service request
132  cpr::Url url = cpr::Url{ servicesUrl_ + "calibrate" };
133  auto rest_resp = cpr::Put(url, cpr::Timeout{ timeoutCurl_ });
134  handleCPRResponse(rest_resp);
135 
136  // parse json response into ros message
137  auto json_resp = json::parse(rest_resp.text)["response"];
138  response.success = (bool) json_resp["success"];
139  response.status = json_resp["status"];
140  response.message = json_resp["message"];
141  response.error = json_resp["error"];
142  response.robot_mounted = (bool) json_resp["robot_mounted"];
143 
144  json js_pose = json_resp["pose"];
145  response.pose.position.x = js_pose["position"]["x"];
146  response.pose.position.y = js_pose["position"]["y"];
147  response.pose.position.z = js_pose["position"]["z"];
148  response.pose.orientation.x = js_pose["orientation"]["x"];
149  response.pose.orientation.y = js_pose["orientation"]["y"];
150  response.pose.orientation.z = js_pose["orientation"]["z"];
151  response.pose.orientation.w = js_pose["orientation"]["w"];
152 
153  return true;
154 }
155 
156 
157 bool CalibrationWrapper::getCalibResultSrv(rc_hand_eye_calibration_client::CalibrationRequest &,
158  rc_hand_eye_calibration_client::CalibrationResponse &response)
159 {
160  // do service request
161  cpr::Url url = cpr::Url{ servicesUrl_ + "get_calibration" };
162  auto rest_resp = cpr::Put(url, cpr::Timeout{ timeoutCurl_ });
163  handleCPRResponse(rest_resp);
164 
165  // parse json response into ros message
166  auto json_resp = json::parse(rest_resp.text)["response"];
167  response.success = (bool) json_resp["success"];
168  response.status = json_resp["status"];
169  response.message = json_resp["message"];
170  response.error = json_resp["error"];
171  response.robot_mounted = (bool) json_resp["robot_mounted"];
172 
173  json js_pose = json_resp["pose"];
174  response.pose.position.x = js_pose["position"]["x"];
175  response.pose.position.y = js_pose["position"]["y"];
176  response.pose.position.z = js_pose["position"]["z"];
177  response.pose.orientation.x = js_pose["orientation"]["x"];
178  response.pose.orientation.y = js_pose["orientation"]["y"];
179  response.pose.orientation.z = js_pose["orientation"]["z"];
180  response.pose.orientation.w = js_pose["orientation"]["w"];
181 
182  return true;
183 }
184 
185 
187 {
188  using CW = CalibrationWrapper;
189  //Save pose and image/grid pair for later calibration
190  srv_set_slot_ = nh_.advertiseService("set_pose", &CW::setSlotSrv, this);
191  //Save calibration to disk
192  srv_save_ = nh_.advertiseService("save_calibration", &CW::saveSrv, this);
193  //Compute and return calibration
194  srv_calibrate_ = nh_.advertiseService("calibrate", &CW::calibSrv, this);
195  //Get result (but don't compute)
196  srv_get_result_ = nh_.advertiseService("get_calibration", &CW::getCalibResultSrv, this);
197  //Delete all slots
198  srv_reset_ = nh_.advertiseService("reset_calibration", &CW::resetSrv, this);
199  // remove calibration
200  srv_remove_ = nh_.advertiseService("remove_calibration", &CW::removeSrv, this);
201 }
202 
204 {
205  rc_hand_eye_calibration_client::hand_eye_calibrationConfig cfg;
206 
207  // first get the current values from sensor
208  auto rest_resp = cpr::Get(paramsUrl_, cpr::Timeout{ timeoutCurl_ });
209  handleCPRResponse(rest_resp);
210  auto json_resp = json::parse(rest_resp.text);
211  for (auto& param : json_resp) {
212  string name = param["name"];
213  if (param["name"] == "grid_width")
214  {
215  cfg.grid_width = param["value"];
216  } else if (param["name"] == "grid_height")
217  {
218  cfg.grid_height = param["value"];
219  } else if (param["name"] == "robot_mounted")
220  {
221  cfg.robot_mounted = (bool) param["value"];
222  }
223  }
224 
225  // second, try to get ROS parameters:
226  // if parameter is not set in parameter server, we default to current sensor configuration
227  nh_.param("grid_width", cfg.grid_width, cfg.grid_width);
228  nh_.param("grid_height", cfg.grid_height, cfg.grid_height);
229  nh_.param("robot_mounted", cfg.robot_mounted, cfg.robot_mounted);
230 
231  // set parameters on parameter server so that dynamic reconfigure picks them up
232  nh_.setParam("grid_width", cfg.grid_width);
233  nh_.setParam("grid_height", cfg.grid_height);
234  nh_.setParam("robot_mounted", cfg.robot_mounted);
235 
236  // instantiate dynamic reconfigure server that will initially read those values
237  using RCFSRV = dynamic_reconfigure::Server<rc_hand_eye_calibration_client::hand_eye_calibrationConfig>;
238  server_ = unique_ptr<RCFSRV>(new dynamic_reconfigure::Server<rc_hand_eye_calibration_client::hand_eye_calibrationConfig>(nh_));
239  server_->setCallback(boost::bind(&CalibrationWrapper::dynamicReconfigureCb, this, _1, _2));
240 }
241 
242 
243 void CalibrationWrapper::dynamicReconfigureCb(rc_hand_eye_calibration_client::hand_eye_calibrationConfig
244  &config,
245  uint32_t)
246 {
247  ROS_DEBUG("Reconfigure Request: (%f x %f) %s",
248  config.grid_width, config.grid_height,
249  config.robot_mounted ? "True" : "False");
250 
251  // fill json request from dynamic reconfigure request
252  json js_params, js_param;
253  js_param["name"] ="grid_width";
254  js_param["value"] = config.grid_width;
255  js_params.push_back(js_param);
256  js_param["name"] ="grid_height";
257  js_param["value"] = config.grid_height;
258  js_params.push_back(js_param);
259  js_param["name"] ="robot_mounted";
260  js_param["value"] = config.robot_mounted;
261  js_params.push_back(js_param);
262 
263  // do service request
264  auto rest_resp = cpr::Put(paramsUrl_, cpr::Timeout{ timeoutCurl_ },
265  cpr::Body{ js_params.dump() },
266  cpr::Header{ { "Content-Type", "application/json" } });
267 
268  handleCPRResponse(rest_resp);
269 }
bool saveSrv(std_srvs::TriggerRequest &request, std_srvs::TriggerResponse &response)
store hand eye calibration on sensor
bool param(const std::string &param_name, T &param_val, const T &default_val)
bool removeSrv(std_srvs::TriggerRequest &request, std_srvs::TriggerResponse &response)
Remove calibration so sensor reports as uncalibrated.
std::unique_ptr< dynamic_reconfigure::Server< rc_hand_eye_calibration_client::hand_eye_calibrationConfig > > server_
void dynamicReconfigureCb(rc_hand_eye_calibration_client::hand_eye_calibrationConfig &config, uint32_t)
bool setSlotSrv(rc_hand_eye_calibration_client::SetCalibrationPoseRequest &request, rc_hand_eye_calibration_client::SetCalibrationPoseResponse &response)
Save given pose and the pose of the grid indexed by the given request.slot.
XmlRpcServer s
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool getCalibResultSrv(rc_hand_eye_calibration_client::CalibrationRequest &request, rc_hand_eye_calibration_client::CalibrationResponse &response)
Service call to get the result. Also returned directly via calibrate.
bool resetSrv(std_srvs::TriggerRequest &request, std_srvs::TriggerResponse &response)
Delete all stored data, e.g., to start over.
void advertiseServices()
Advertises the services in the namespace of nh_.
bool calibSrv(rc_hand_eye_calibration_client::CalibrationRequest &request, rc_hand_eye_calibration_client::CalibrationResponse &response)
Perform the calibration and return its result.
bool param(const std::string &param_name, T &param_val, const T &default_val) const
CalibrationWrapper(std::string host, ros::NodeHandle nh)
nlohmann::json json
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
#define ROS_DEBUG(...)


rc_hand_eye_calibration_client
Author(s): Christian Emmerich
autogenerated on Wed Mar 20 2019 07:55:45