8#include <RobotsIO/Hand/iCubHand.h>
10#include <yarp/eigen/Eigen.h>
11#include <yarp/os/Property.h>
12#include <yarp/os/ResourceFinder.h>
13#include <yarp/sig/Vector.h>
19using namespace RobotsIO::Hand;
20using namespace iCub::iKin;
21using namespace yarp::dev;
22using namespace yarp::eigen;
23using namespace yarp::os;
24using namespace yarp::sig;
29 const std::string& robot_name,
30 const std::string& laterality,
31 const std::string& port_prefix,
32 const std::string& context,
33 const bool& use_analogs,
34 const std::string& thumb_version
36 use_analogs_(use_analogs)
39 if (!yarp_.checkNetwork())
41 throw(std::runtime_error(log_name_ +
"::ctor. Error: YARP network is not available."));
45 if ((laterality !=
"right") && (laterality !=
"left"))
47 throw std::runtime_error(log_name_ +
"::ctor. Error: invalid laterality" + laterality +
".");
55 rf.setDefaultConfigFile(
"icub_hand_configuration.ini");
56 rf.setDefaultContext(context);
57 rf.configure(0, NULL);
60 ResourceFinder inner_rf = rf.findNestedResourceFinder(laterality.c_str());
61 bool use_bounds_ = inner_rf.check(
"use_bounds", Value(
false)).asBool();
65 yarp::sig::Vector bounds_col_0;
66 std::tie(valid_vector, bounds_col_0) = load_vector_double(inner_rf,
"bounds_col_0", 16);
69 throw std::runtime_error(log_name_ +
"::ctor. Error: bounds requested but not available in the configuration file.");
72 yarp::sig::Vector bounds_col_1;
73 std::tie(valid_vector, bounds_col_1) = load_vector_double(inner_rf,
"bounds_col_1", 16);
76 throw std::runtime_error(log_name_ +
"::ctor. Error: bounds requested but not available in the configuration file.");
79 analog_bounds_.resize(16, 2);
80 analog_bounds_.setCol(0, bounds_col_0);
81 analog_bounds_.setCol(1, bounds_col_1);
86 prop_analog.put(
"device",
"analogsensorclient");
87 prop_analog.put(
"local",
"/" + port_prefix +
"/" + laterality +
"_hand/analog:i");
88 prop_analog.put(
"remote",
"/" + robot_name +
"/" + laterality +
"_hand/analog:o");
89 if (drv_analog_.open(prop_analog))
92 if (drv_analog_.view(ianalog_) && ianalog_ !=
nullptr)
93 use_interface_analogs_ =
true;
96 if (!use_interface_analogs_)
99 std::cout << log_name_ +
"::ctor. Info: PolyDriver interface IAnalogSensors not available. Using raw encoders from a port." << std::endl;
101 if (!port_analogs_.open(
"/" + port_prefix +
"/" + laterality +
"_hand/analog:i"))
103 throw std::runtime_error(log_name_ +
"::ctor. Error: unable to open port for analog encoders.");
109 Property prop_encoders;
110 prop_encoders.put(
"device",
"remote_controlboard");
111 prop_encoders.put(
"local",
"/" + port_prefix +
"/" + laterality +
"_arm");
112 prop_encoders.put(
"remote",
"/" + robot_name +
"/" + laterality +
"_arm");
113 if (drv_arm_.open(prop_encoders))
116 if (drv_arm_.view(iarm_) && iarm_ !=
nullptr)
117 use_interface_arm_ =
true;
120 if (!(drv_arm_.view(ilimits_)) || (ilimits_ ==
nullptr))
121 throw std::runtime_error(log_name_ +
"::ctor. Error: unable get view for finger control limits.");
124 if (!use_interface_arm_)
127 std::cout << log_name_ +
"::ctor. Info: PolyDriver interface IEncoders not available. Using raw encoders from a port." << std::endl;
129 if (!port_arm_.open(
"/" + port_prefix +
"/" + laterality +
"_arm"))
131 throw std::runtime_error(log_name_ +
"::ctor. Error: unable to open port for arm encoders.");
136 std::string thumb_key =
"thumb";
137 if (!thumb_version.empty())
138 thumb_key +=
"_" + thumb_version;
139 fingers_[
"thumb"] = iCubFinger(laterality +
"_" + thumb_key);
140 fingers_[
"index"] = iCubFinger(laterality +
"_index");
141 fingers_[
"middle"] = iCubFinger(laterality +
"_middle");
142 fingers_[
"ring"] = iCubFinger(laterality +
"_ring");
143 fingers_[
"little"] = iCubFinger(laterality +
"_little");
148 std::deque<IControlLimits*> limits;
149 limits.push_back(ilimits_);
150 for (
auto& finger : fingers_)
151 finger.second.alignJointsBounds(limits);
166 if (use_interface_arm_)
173std::pair<bool, std::unordered_map<std::string, Eigen::VectorXd>> iCubHand::encoders(
const bool& blocking)
176 yarp::sig::Vector analogs(15);
177 bool outcome_analog =
false;
182 outcome_analog = (ianalog_->read(analogs)) == (IAnalogSensor::AS_OK);
187 if (bottle_analogs !=
nullptr)
189 for (
size_t i = 0; i < analogs.size(); i++)
190 analogs(i) = bottle_analogs->get(i).asFloat64();
192 outcome_analog =
true;
198 yarp::sig::Vector encoders(9);
200 bool outcome_arm =
false;
203 yarp::sig::Vector arm(16);
205 if (use_interface_arm_)
206 outcome_arm = iarm_->getEncoders(arm.data());
209 Bottle* bottle_arm = port_arm_.read(blocking);
211 if (bottle_arm !=
nullptr)
213 for (
size_t i = 0; i < arm.size(); i++)
214 arm(i) = bottle_arm->get(i).asFloat64();
221 toEigen(encoders) = toEigen(arm).segment<9>(7);
226 if (!(outcome_analog && outcome_arm))
227 return std::make_pair(
false, std::unordered_map<std::string, VectorXd>());
232 return std::make_pair(
false, std::unordered_map<std::string, VectorXd>());
236 std::unordered_map<std::string, VectorXd> output_encoders;
239 yarp::sig::Vector chain_joints;
243 finger.second.getChainJoints(encoders, analogs, chain_joints,
analog_bounds_);
245 finger.second.getChainJoints(encoders, analogs, chain_joints);
248 finger.second.getChainJoints(encoders, chain_joints);
250 VectorXd chain_joints_eigen = toEigen(chain_joints) * M_PI / 180.0;
251 output_encoders[finger.first] = chain_joints_eigen;
254 return std::make_pair(
true, output_encoders);
258std::pair<bool, yarp::sig::Vector> iCubHand::load_vector_double(
const ResourceFinder& rf,
const std::string key,
const std::size_t size)
262 if (rf.find(key).isNull())
265 Bottle* b = rf.find(key).asList();
269 if (b->size() != size)
273 return std::make_pair(
false, yarp::sig::Vector());
275 yarp::sig::Vector vector(size);
276 for (std::size_t i = 0; i < b->size(); i++)
278 Value item_v = b->get(i);
280 return std::make_pair(
false, yarp::sig::Vector());
282 if (!item_v.isFloat64())
283 return std::make_pair(
false, yarp::sig::Vector());
285 vector(i) = item_v.asFloat64();
288 return std::make_pair(
true, vector);
std::unordered_map< std::string, iCub::iKin::iCubFinger > fingers_
yarp::dev::PolyDriver drv_analog_
yarp::sig::Matrix analog_bounds_
bool use_interface_analogs_
yarp::os::BufferedPort< yarp::os::Bottle > port_analogs_