rc_silhouettematch_client.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Roboception GmbH
3  *
4  * Author: Elena Gambaro
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of the copyright holder nor the names of its contributors
17  * may be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
34 #include "json_conversions.h"
35 #include "visualizer.h"
36 
38 
40 {
42  : nh_(nh)
43  , rest_helper_(new rc_rest_api::RestHelper(host, "rc_silhouettematch", 10000))
44 {
45  srvs_.emplace_back(nh.advertiseService("detect_object", &SilhouetteMatchClient::detectObject, this));
46  srvs_.emplace_back(nh.advertiseService("calibrate_base_plane", &SilhouetteMatchClient::calibrateBasePlane, this));
47  srvs_.emplace_back(
48  nh.advertiseService("get_base_plane_calibration", &SilhouetteMatchClient::getBasePlaneCalib, this));
49  srvs_.emplace_back(
50  nh.advertiseService("delete_base_plane_calibration", &SilhouetteMatchClient::deleteBasePlaneCalib, this));
51 
53 }
54 
56 
57 template <typename Request, typename Response>
58 bool SilhouetteMatchClient::callService(const std::string& name, const Request& req, Response& res)
59 {
60  try
61  {
62  json j_req = req;
63  const auto j_res = rest_helper_->servicePutRequest(name, j_req);
64  res = j_res;
65  return true;
66  }
68  {
69  ROS_ERROR("This rc_visard firmware does not support \"%s\"", ex.what());
70  res.return_code.value = -8; // NOT_APPLICABLE
71  res.return_code.message = "Not available in this firmware version";
72  return false;
73  }
74  catch (const std::exception& ex)
75  {
76  ROS_ERROR("%s", ex.what());
77  res.return_code.value = -2; // INTERNAL_ERROR
78  res.return_code.message = ex.what();
79  return false;
80  }
81 }
82 
83 bool SilhouetteMatchClient::detectObject(DetectObject::Request& req, DetectObject::Response& res)
84 {
85  bool success = callService("detect_object", req, res);
86  if (success && res.return_code.value >= 0 && visualizer_)
87  {
88  visualizer_->visInstances(res.instances);
89  }
90  return true;
91 }
92 
93 bool SilhouetteMatchClient::calibrateBasePlane(CalibrateBasePlane::Request& req, CalibrateBasePlane::Response& res)
94 {
95  bool success = callService("calibrate_base_plane", req, res);
96  if (success && res.return_code.value >= 0 && visualizer_)
97  {
98  visualizer_->visBasePlane(res.plane, res.timestamp);
99  }
100  return true;
101 }
102 
103 bool SilhouetteMatchClient::getBasePlaneCalib(GetBasePlaneCalibration::Request& req,
104  GetBasePlaneCalibration::Response& res)
105 {
106  callService("get_base_plane_calibration", req, res);
107  return true;
108 }
109 
110 bool SilhouetteMatchClient::deleteBasePlaneCalib(DeleteBasePlaneCalibration::Request& req,
111  DeleteBasePlaneCalibration::Response& res)
112 {
113  callService("delete_base_plane_calibration", req, res);
114  return true;
115 }
116 
117 void paramsToCfg(const json& params, SilhouetteMatchConfig& cfg)
118 {
119  for (const auto& param : params)
120  {
121  const auto& name = param["name"];
122  if (name == "max_number_of_detected_objects")
123  cfg.max_number_of_detected_objects = param["value"];
124  else if (name == "edge_sensitivity")
125  cfg.edge_sensitivity = param["value"];
126  else if (name == "match_max_distance")
127  cfg.match_max_distance = param["value"];
128  else if (name == "match_percentile")
129  cfg.match_percentile = param["value"];
130  else if (name == "quality")
131  cfg.quality = param["value"];
132  }
133 }
134 
136 {
137  // first get the current values from sensor
138  const auto j_params = rest_helper_->getParameters();
139  SilhouetteMatchConfig cfg;
140 
141  paramsToCfg(j_params, cfg);
142 
143  // second, try to get ROS parameters:
144  // if param is not set in parameter server, default to current sensor value
145  nh_.param("max_number_of_detected_objects", cfg.max_number_of_detected_objects, cfg.max_number_of_detected_objects);
146  nh_.param("edge_sensitivity", cfg.edge_sensitivity, cfg.edge_sensitivity);
147  nh_.param("match_max_distance", cfg.match_max_distance, cfg.match_max_distance);
148  nh_.param("match_percentile", cfg.match_percentile, cfg.match_percentile);
149  nh_.param("quality", cfg.quality, cfg.quality);
150 
151  // set parameters on parameter server so that dynamic reconfigure picks them up
152  nh_.setParam("max_number_of_detected_objects", cfg.max_number_of_detected_objects);
153  nh_.setParam("edge_sensitivity", cfg.edge_sensitivity);
154  nh_.setParam("match_max_distance", cfg.match_max_distance);
155  nh_.setParam("match_percentile", cfg.match_percentile);
156  nh_.setParam("quality", cfg.quality);
157 
158  // instantiate dynamic reconfigure server that will initially read those values
159  using ReconfServer = dynamic_reconfigure::Server<SilhouetteMatchConfig>;
160  dyn_reconf_ = std::unique_ptr<ReconfServer>(new ReconfServer(nh_));
161  dyn_reconf_->setCallback(boost::bind(&SilhouetteMatchClient::updateParameters, this, _1, _2));
162 }
163 
164 void SilhouetteMatchClient::updateParameters(SilhouetteMatchConfig& config, uint32_t)
165 {
166  json j_params;
167  j_params.emplace_back(
168  json{ { "name", "max_number_of_detected_objects" }, { "value", config.max_number_of_detected_objects } });
169  j_params.emplace_back(json{ { "name", "edge_sensitivity" }, { "value", config.edge_sensitivity } });
170  j_params.emplace_back(json{ { "name", "match_max_distance" }, { "value", config.match_max_distance } });
171  j_params.emplace_back(json{ { "name", "match_percentile" }, { "value", config.match_percentile } });
172  j_params.emplace_back(json{ { "name", "quality" }, { "value", config.quality } });
173 
174  if (config.publish_vis)
175  {
176  if (!visualizer_)
177  visualizer_.reset(new Visualizer(nh_));
178  }
179  else
180  {
181  visualizer_.reset();
182  }
183 
184  json j_params_new = rest_helper_->setParameters(j_params);
185  // set config with new params so they are updated if needed
186  paramsToCfg(j_params_new, config);
187 }
188 
189 } // namespace rc_silhouettematch_client
bool param(const std::string &param_name, T &param_val, const T &default_val)
void updateParameters(SilhouetteMatchConfig &config, uint32_t)
nlohmann::json json
bool detectObject(DetectObject::Request &req, DetectObject::Response &res)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool callService(const std::string &name, const Request &req, Response &res)
void paramsToCfg(const json &params, SilhouetteMatchConfig &cfg)
SilhouetteMatchClient(const std::string &host, ros::NodeHandle &nh)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
std::unique_ptr< rc_rest_api::RestHelper > rest_helper_
std::unique_ptr< dynamic_reconfigure::Server< SilhouetteMatchConfig > > dyn_reconf_
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
bool deleteBasePlaneCalib(DeleteBasePlaneCalibration::Request &req, DeleteBasePlaneCalibration::Response &res)
bool getBasePlaneCalib(GetBasePlaneCalibration::Request &req, GetBasePlaneCalibration::Response &res)
bool calibrateBasePlane(CalibrateBasePlane::Request &req, CalibrateBasePlane::Response &res)
#define ROS_ERROR(...)


rc_silhouettematch_client
Author(s): Elena Gambaro
autogenerated on Sun May 15 2022 03:05:23