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  srvs_.emplace_back(nh.advertiseService("set_region_of_interest_2d", &SilhouetteMatchClient::setROI, this));
52  srvs_.emplace_back(nh.advertiseService("get_regions_of_interest_2d", &SilhouetteMatchClient::getROIs, this));
53  srvs_.emplace_back(nh.advertiseService("delete_regions_of_interest_2d", &SilhouetteMatchClient::deleteROIs, this));
54 
56 }
57 
59 
60 template <typename Request, typename Response>
61 bool SilhouetteMatchClient::callService(const std::string& name, const Request& req, Response& res)
62 {
63  try
64  {
65  json j_req = req;
66  const auto j_res = rest_helper_->servicePutRequest(name, j_req);
67  res = j_res;
68  return true;
69  }
71  {
72  ROS_ERROR("This rc_visard firmware does not support \"%s\"", ex.what());
73  res.return_code.value = -8; // NOT_APPLICABLE
74  res.return_code.message = "Not available in this firmware version";
75  return false;
76  }
77  catch (const std::exception& ex)
78  {
79  ROS_ERROR("%s", ex.what());
80  res.return_code.value = -2; // INTERNAL_ERROR
81  res.return_code.message = ex.what();
82  return false;
83  }
84 }
85 
86 bool SilhouetteMatchClient::detectObject(DetectObject::Request& req, DetectObject::Response& res)
87 {
88  bool success = callService("detect_object", req, res);
89  if (success && res.return_code.value >= 0 && visualizer_)
90  {
91  visualizer_->visInstances(res.instances);
92  }
93  return true;
94 }
95 
96 bool SilhouetteMatchClient::calibrateBasePlane(CalibrateBasePlane::Request& req, CalibrateBasePlane::Response& res)
97 {
98  bool success = callService("calibrate_base_plane", req, res);
99  if (success && res.return_code.value >= 0 && visualizer_)
100  {
101  visualizer_->visBasePlane(res.plane, res.timestamp);
102  }
103  return true;
104 }
105 
106 bool SilhouetteMatchClient::getBasePlaneCalib(GetBasePlaneCalibration::Request& req,
107  GetBasePlaneCalibration::Response& res)
108 {
109  callService("get_base_plane_calibration", req, res);
110  return true;
111 }
112 
113 bool SilhouetteMatchClient::deleteBasePlaneCalib(DeleteBasePlaneCalibration::Request& req,
114  DeleteBasePlaneCalibration::Response& res)
115 {
116  callService("delete_base_plane_calibration", req, res);
117  return true;
118 }
119 
120 bool SilhouetteMatchClient::setROI(SetRegionOfInterest::Request& req, SetRegionOfInterest::Response& res)
121 {
122  callService("set_region_of_interest_2d", req, res);
123  return true;
124 }
125 
126 bool SilhouetteMatchClient::getROIs(GetRegionsOfInterest::Request& req, GetRegionsOfInterest::Response& res)
127 {
128  callService("get_regions_of_interest_2d", req, res);
129  return true;
130 }
131 
132 bool SilhouetteMatchClient::deleteROIs(DeleteRegionsOfInterest::Request& req, DeleteRegionsOfInterest::Response& res)
133 {
134  callService("delete_regions_of_interest_2d", req, res);
135  return true;
136 }
137 
138 void paramsToCfg(const json& params, SilhouetteMatchConfig& cfg)
139 {
140  for (const auto& param : params)
141  {
142  const auto& name = param["name"];
143  if (name == "max_number_of_detected_objects")
144  cfg.max_number_of_detected_objects = param["value"];
145  else if (name == "edge_sensitivity")
146  cfg.edge_sensitivity = param["value"];
147  else if (name == "match_max_distance")
148  cfg.match_max_distance = param["value"];
149  else if (name == "match_percentile")
150  cfg.match_percentile = param["value"];
151  else if (name == "quality")
152  cfg.quality = param["value"];
153  }
154 }
155 
157 {
158  // first get the current values from sensor
159  const auto j_params = rest_helper_->getParameters();
160  SilhouetteMatchConfig cfg;
161 
162  paramsToCfg(j_params, cfg);
163 
164  // second, try to get ROS parameters:
165  // if param is not set in parameter server, default to current sensor value
166  nh_.param("max_number_of_detected_objects", cfg.max_number_of_detected_objects, cfg.max_number_of_detected_objects);
167  nh_.param("edge_sensitivity", cfg.edge_sensitivity, cfg.edge_sensitivity);
168  nh_.param("match_max_distance", cfg.match_max_distance, cfg.match_max_distance);
169  nh_.param("match_percentile", cfg.match_percentile, cfg.match_percentile);
170  nh_.param("quality", cfg.quality, cfg.quality);
171 
172  // set parameters on parameter server so that dynamic reconfigure picks them up
173  nh_.setParam("max_number_of_detected_objects", cfg.max_number_of_detected_objects);
174  nh_.setParam("edge_sensitivity", cfg.edge_sensitivity);
175  nh_.setParam("match_max_distance", cfg.match_max_distance);
176  nh_.setParam("match_percentile", cfg.match_percentile);
177  nh_.setParam("quality", cfg.quality);
178 
179  // instantiate dynamic reconfigure server that will initially read those values
180  using ReconfServer = dynamic_reconfigure::Server<SilhouetteMatchConfig>;
181  dyn_reconf_ = std::unique_ptr<ReconfServer>(new ReconfServer(nh_));
182  dyn_reconf_->setCallback(boost::bind(&SilhouetteMatchClient::updateParameters, this, _1, _2));
183 }
184 
185 void SilhouetteMatchClient::updateParameters(SilhouetteMatchConfig& config, uint32_t)
186 {
187  json j_params;
188  j_params.emplace_back(
189  json{ { "name", "max_number_of_detected_objects" }, { "value", config.max_number_of_detected_objects } });
190  j_params.emplace_back(json{ { "name", "edge_sensitivity" }, { "value", config.edge_sensitivity } });
191  j_params.emplace_back(json{ { "name", "match_max_distance" }, { "value", config.match_max_distance } });
192  j_params.emplace_back(json{ { "name", "match_percentile" }, { "value", config.match_percentile } });
193  j_params.emplace_back(json{ { "name", "quality" }, { "value", config.quality } });
194 
195  if (config.publish_vis)
196  {
197  if (!visualizer_)
198  visualizer_.reset(new Visualizer(nh_));
199  }
200  else
201  {
202  visualizer_.reset();
203  }
204 
205  json j_params_new = rest_helper_->setParameters(j_params);
206  // set config with new params so they are updated if needed
207  paramsToCfg(j_params_new, config);
208 }
209 
210 } // namespace rc_silhouettematch_client
bool param(const std::string &param_name, T &param_val, const T &default_val)
void updateParameters(SilhouetteMatchConfig &config, uint32_t)
bool getROIs(GetRegionsOfInterest::Request &req, GetRegionsOfInterest::Response &res)
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)
std::unique_ptr< rc_rest_api::RestHelper > rest_helper_
bool param(const std::string &param_name, T &param_val, const T &default_val) const
std::unique_ptr< dynamic_reconfigure::Server< SilhouetteMatchConfig > > dyn_reconf_
bool deleteROIs(DeleteRegionsOfInterest::Request &req, DeleteRegionsOfInterest::Response &res)
bool deleteBasePlaneCalib(DeleteBasePlaneCalibration::Request &req, DeleteBasePlaneCalibration::Response &res)
bool getBasePlaneCalib(GetBasePlaneCalibration::Request &req, GetBasePlaneCalibration::Response &res)
bool setROI(SetRegionOfInterest::Request &req, SetRegionOfInterest::Response &res)
bool calibrateBasePlane(CalibrateBasePlane::Request &req, CalibrateBasePlane::Response &res)
#define ROS_ERROR(...)
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const


rc_silhouettematch_client
Author(s): Elena Gambaro
autogenerated on Sat Feb 13 2021 03:42:03