88 {
return taskFactory->createTask(); }
94 using dev_group_t = std::tuple<const RawDevice *, std::vector<int>,
int>;
100 const std::vector<std::unique_ptr<const RawDevice>> &
getDevices()
const
135 {
return totalAxes; }
138#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
139 template<
typename T,
typename... T_ref>
142 template<
typename T,
typename... T_ref>
143 using motor_single_joint_const_fn = yarp::dev::ReturnValue (T::*)(int, T_ref...) const;
145 template<
typename T,
typename... T_ref>
150 template<
typename T,
typename... T_ref,
typename... Args>
151#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
158 auto * p = device ? device->getHandle<T>() :
nullptr;
159#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
160 return p ? std::invoke(fn, p, offset, std::forward<Args>(args)...) : yarp::dev::ReturnValue_error_method_failed;
162 return p && std::invoke(fn, p, offset, std::forward<Args>(args)...);
166#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
168 template<
typename T,
typename... T_ref,
typename... Args>
169 yarp::dev::ReturnValue
mapSingleJoint(motor_single_joint_const_fn<T, T_ref...> fn,
int j, Args &&... args)
const
172 auto * p = device ? device->getHandle<T>() : nullptr;
173 return p ? std::invoke(fn, p, offset, std::forward<Args>(args)...) : yarp::dev::ReturnValue_error_method_failed;
178 template<
typename T,
typename... T_refs>
179#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
186 template<
typename T,
typename... T_refs>
187#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
198 auto * p = device ? device->template getHandle<T>() :
nullptr;
199 ok |= p && (task->add(p, fn, refs + offset...),
true);
203#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
204 return ok && task->dispatch() ? yarp::dev::ReturnValue_ok : yarp::dev::ReturnValue_error_method_failed;
206 return ok && task->dispatch();
210#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
211 template<
typename T,
typename Elem>
212 using motor_all_joints_vec_fn = yarp::dev::ReturnValue (T::*)(std::vector<Elem> &);
215 template<
typename T,
typename Elem>
216 yarp::dev::ReturnValue
mapAllJoints(motor_all_joints_vec_fn<T, Elem> fn, std::vector<Elem> & vec)
223 struct DeviceSubSlice
226 std::vector<Elem> sub_vec;
229 auto slices = std::make_shared<std::vector<DeviceSubSlice>>();
231 for (
auto i = 0; i < devices.size(); i++)
233 auto [device, offset] = devices[i];
234 auto * p = device ? device->template getHandle<T>() : nullptr;
238 auto next_offset = (i + 1 < devices.size()) ? std::get<1>(devices[i + 1]) : vec.size();
239 slices->push_back({offset, std::vector(vec.begin() + offset, vec.begin() + next_offset)});
240 ok |= (task->add(p, fn, std::ref(slices->back().sub_vec)),
true);
244 ok &= task->dispatch();
248 for (
const auto & slice : *slices)
250 std::copy(slice.sub_vec.begin(), slice.sub_vec.end(), vec.begin() + slice.offset);
254 return ok ? yarp::dev::ReturnValue_ok : yarp::dev::ReturnValue_error_method_failed;
257 template<
typename T,
typename Elem>
258 using motor_all_joints_const_vec_fn = yarp::dev::ReturnValue (T::*)(const std::vector<Elem> &);
261 template<
typename T,
typename Elem>
262 yarp::dev::ReturnValue
mapAllJoints(motor_all_joints_const_vec_fn<T, Elem> fn,
const std::vector<Elem> & vec)
268 for (
auto i = 0; i < devices.size(); i++)
270 auto [device, offset] = devices[i];
271 auto * p = device ? device->template getHandle<T>() : nullptr;
275 auto next_offset = (i + 1 < devices.size()) ? std::get<1>(devices[i + 1]) : vec.size();
276 ok |= (task->add(p, fn, std::vector(vec.begin() + offset, vec.begin() + next_offset)),
true);
280 return ok && task->dispatch() ? yarp::dev::ReturnValue_ok : yarp::dev::ReturnValue_error_method_failed;
285 template<
typename T,
typename... T_refs>
286#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
293 template<
typename T,
typename... T_refs>
294#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
304 for (
const auto & [device, localIndices, globalIndex] : devices)
306 auto * p = device ? device->template getHandle<T>() :
nullptr;
307 ok &= p && (task->add(p, fn, localIndices.size(), localIndices.data(), refs + globalIndex...),
true);
311#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
312 return ok && task->dispatch() ? yarp::dev::ReturnValue_ok : yarp::dev::ReturnValue_error_method_failed;
314 return ok && task->dispatch();
318#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
319 template<
typename T,
typename Elem>
320 using motor_multi_joints_vec_fn = yarp::dev::ReturnValue (T::*)(const std::vector<int> &, std::vector<Elem> &);
323 template<
typename T,
typename Elem>
324 yarp::dev::ReturnValue
mapJointGroup(motor_multi_joints_vec_fn<T, Elem> fn,
const std::vector<int> & joints, std::vector<Elem> & vec)
333 std::vector<size_t> global_indices;
334 std::vector<int> local_indices;
335 std::vector<Elem> sub_vec;
338 auto slices = std::make_shared<std::vector<SliceInfo>>();
339 slices->reserve(devices.size());
341 for (
const auto & [device, localIndices, globalIndex] : devices)
343 auto * p = device ? device->template getHandle<T>() : nullptr;
348 info.local_indices = localIndices;
349 info.global_indices.reserve(localIndices.size());
350 info.sub_vec.reserve(localIndices.size());
353 for (
auto i = 0; i < localIndices.size(); ++i)
355 auto g_idx = globalIndex + i;
356 info.global_indices.push_back(g_idx);
357 info.sub_vec.push_back(vec[g_idx]);
360 slices->push_back(std::move(info));
361 auto & current = slices->back();
362 ok &= (task->add(p, fn, std::cref(current.local_indices), std::ref(current.sub_vec)),
true);
366 ok &= task->dispatch();
370 for (
const auto & slice : *slices)
372 for (
auto i = 0; i < slice.sub_vec.size(); ++i)
374 vec[slice.global_indices[i]] = slice.sub_vec[i];
379 return ok ? yarp::dev::ReturnValue_ok : yarp::dev::ReturnValue_error_method_failed;
382 template<
typename T,
typename Elem>
383 using motor_multi_joints_const_vec_fn = yarp::dev::ReturnValue (T::*)(const std::vector<int> &, const std::vector<Elem> &);
386 template<
typename T,
typename Elem>
387 yarp::dev::ReturnValue
mapJointGroup(motor_multi_joints_const_vec_fn<T, Elem> fn,
const std::vector<int> & joints,
const std::vector<Elem> & vec)
395 std::vector<int> local_indices;
396 std::vector<Elem> sub_vec;
399 auto slices = std::make_shared<std::vector<SliceInfo>>();
400 slices->reserve(devices.size());
402 for (
const auto & [device, localIndices, globalIndex] : devices)
404 auto * p = device->template getHandle<T>();
409 info.local_indices = localIndices;
410 info.sub_vec.reserve(localIndices.size());
412 for (
auto i = 0; i < localIndices.size(); ++i)
414 info.sub_vec.push_back(vec[globalIndex + i]);
417 slices->push_back(std::move(info));
418 auto & current = slices->back();
419 ok &= (task->add(p, fn, std::cref(current.local_indices), std::cref(current.sub_vec)),
true);
423 return ok && task->dispatch() ? yarp::dev::ReturnValue_ok : yarp::dev::ReturnValue_error_method_failed;
429#if YARP_VERSION_COMPARE(>=, 4, 1, 0) || defined(YARP_NEXT)
436 if (
auto it = connectedSensors.find(
typeid(T)); it != connectedSensors.cend())
438#if YARP_VERSION_COMPARE(>=, 4, 1, 0) || defined(YARP_NEXT)
440 return yarp::dev::ReturnValue_ok;
446#if YARP_VERSION_COMPARE(>=, 4, 1, 0) || defined(YARP_NEXT)
447 return yarp::dev::ReturnValue_error_method_failed;
462 if (
auto it = sensorOffsets.find(
typeid(T)); it != sensorOffsets.cend())
464 const auto & [deviceIndex, offset, count] = it->second[globalIndex];
465 return {devices[deviceIndex].get(), globalIndex - offset};
471 template<
typename T,
typename T_out>
472 using sensor_status_fn = T_out (T::*)(std::size_t) const;
478 template<
typename T,
typename T_out>
481 auto [device, offset] = getSensorDevice<T>(index);
482 auto * p = device->template getHandle<T>();
483 return p ? std::invoke(fn, p, offset) :
static_cast<T_out
>(DeviceMapper::getSensorFailureStatus());
487 using sensor_size_fn = std::size_t (T::*)(std::size_t) const;
496 auto [device, offset] = getSensorDevice<T>(index);
497 auto * p = device->template getHandle<T>();
498 return p ? std::invoke(fn, p, offset) : 0;
501 template<
typename T,
typename... T_out_params>
502#if YARP_VERSION_COMPARE(>=, 4, 1, 0) || defined(YARP_NEXT)
503 using sensor_output_fn = yarp::dev::ReturnValue (T::*)(std::size_t, T_out_params &...) const;
505 using sensor_output_fn = bool (T::*)(std::size_t, T_out_params &...) const;
512 template<
typename T,
typename... T_out_params>
513#if YARP_VERSION_COMPARE(>=, 4, 1, 0) || defined(YARP_NEXT)
514 yarp::dev::ReturnValue
getSensorOutput(sensor_output_fn<T, T_out_params...> fn, std::size_t index, T_out_params &... params)
const
516 bool getSensorOutput(sensor_output_fn<T, T_out_params...> fn, std::size_t index, T_out_params &... params)
const
519 auto [device, offset] = getSensorDevice<T>(index);
520 auto * p = device->template getHandle<T>();
521#if YARP_VERSION_COMPARE(>=, 4, 1, 0) || defined(YARP_NEXT)
522 return p ? std::invoke(fn, p, offset, params...) : yarp::dev::ReturnValue_error_method_failed;
524 return p ? std::invoke(fn, p, offset, params...) :
false;
529 static const int getSensorFailureStatus();
531 using dev_index_offset_t = std::tuple<int, int, int>;
533 std::vector<std::unique_ptr<const RawDevice>> devices;
534 std::vector<dev_index_offset_t> motorOffsets;
535 std::unordered_map<std::type_index, std::vector<dev_index_offset_t>> sensorOffsets;
536 std::unordered_map<std::type_index, std::size_t> connectedSensors;
540 std::unique_ptr<FutureTaskFactory> taskFactory;