-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathIKWorkerPool.h
182 lines (142 loc) · 5.65 KB
/
IKWorkerPool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
* Copyright (C) 2018 Istituto Italiano di Tecnologia (IIT)
* All rights reserved.
*
* This software may be modified and distributed under the terms of the
* GNU Lesser General Public License v2.1 or any later version.
*/
#ifndef IKWORKERPOOL_H
#define IKWORKERPOOL_H
#include <vector>
#include <memory>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <unordered_map>
#include <iDynTree/Core/MatrixDynSize.h>
#include <iDynTree/Core/VectorDynSize.h>
#include <iDynTree/Core/Transform.h>
#include <iDynTree/Model/Model.h>
#include <iDynTree/Model/Indices.h>
#include <iDynTree/Model/JointState.h>
#include <iDynTree/KinDynComputations.h>
#include <iDynTree/InverseKinematics.h>
#include <Eigen/QR>
#include <yarp/sig/Vector.h>
/*!
* Relevant information on the submodel between two links (segments)
* Needed to compute inverse kinematics, velocities, etc
*/
struct LinkPairInfo {
// Variables representing the DoFs between the two frames
iDynTree::VectorDynSize jointConfigurations;
iDynTree::VectorDynSize jointVelocities;
// Transformation variable
iDynTree::Transform relativeTransformation; // TODO: If this is wrt global frame
// IK elements (i.e. compute joints)
std::shared_ptr<iDynTree::InverseKinematics> ikSolver;
double positionTargetWeight;
double rotationTargetWeight;
double costRegularization;
// Initial joint positions
iDynTree::VectorDynSize sInitial;
// Reduced model of link pair
iDynTree::Model pairModel;
// Floating base variables
iDynTree::LinkIndex floatingBaseIndex;
iDynTree::Transform floatingBaseTransform;
// Velocity-related elements
iDynTree::MatrixDynSize relativeJacobian;
std::unique_ptr<iDynTree::KinDynComputations> kinDynComputations;
// Mapping from link pair to full model. Needed to map from small to complete problem
std::string parentFrameName; //name of the parent frame
iDynTree::FrameIndex parentFrameModelIndex; //index of the frame in the iDynTree Model
iDynTree::FrameIndex parentFrameSegmentsIndex; //index of the parent frame in the segment list
std::string childFrameName; //name of the child frame
iDynTree::FrameIndex childFrameModelIndex; //index of the frame in the iDynTree Model
iDynTree::FrameIndex childFrameSegmentsIndex; //index of the child frame in the segment list
std::vector<std::pair<size_t, size_t>> consideredJointLocations; /*!< For each joint connecting the pair: first = offset in the full model , second = dofs of joint */
LinkPairInfo() = default;
#if defined(_MSC_VER) && _MSC_VER < 1900
LinkPairInfo(LinkPairInfo&& rvalue)
: jointConfigurations(std::move(rvalue.jointConfigurations))
, jointVelocities(std::move(rvalue.jointVelocities))
, ikSolver(std::move(rvalue.ikSolver))
, relativeJacobian(std::move(rvalue.relativeJacobian))
, kinDynComputations(std::move(rvalue.kinDynComputations))
, parentFrameName(std::move(rvalue.parentFrameName))
, parentFrameModelIndex(rvalue.parentFrameModelIndex)
, parentFrameSegmentsIndex(rvalue.parentFrameSegmentsIndex)
, childFrameName(std::move(rvalue.childFrameName))
, childFrameModelIndex(rvalue.childFrameModelIndex)
, childFrameSegmentsIndex(rvalue.childFrameSegmentsIndex)
, consideredJointLocations(std::move(rvalue.consideredJointLocations))
{}
#else
LinkPairInfo(LinkPairInfo&&) = default;
#endif
LinkPairInfo(const LinkPairInfo&) = delete;
};
// Relevant information on the segment input
struct SegmentInfo {
std::string segmentName;
iDynTree::Transform poseWRTWorld;
iDynTree::Twist velocities;
// TODO: if not needed acceleration delete them
yarp::sig::Vector accelerations;
};
/*!
* Handles computations related to a single frame pairs.
* This computations at the current stage are:
* - IK given the relative transform
* - joint velocities given the relative (angular) velocity
*/
class IKWorkerPool {
struct WorkerTaskData {
LinkPairInfo& pairInfo;
SegmentInfo& parentFrameInfo;
SegmentInfo& childFrameInfo;
iDynTree::VectorDynSize& sInitial;
long identifier;
};
//I need the following: size of pool
// with special: -1 : 1:1
// 0: only one thread (i.e. same as 1)
// > 0: pool
//Then I need references to the following objects:
//std::vector ok IKSolverData
//resulting buffers: - vectors of final joint configuration
// - vector of poses read from the Xsens
// References to work data
std::vector<LinkPairInfo> &m_linkPairs;
std::vector<SegmentInfo> &m_segments;
// Objects to manage the pool
std::queue<WorkerTaskData> m_tasks;
std::condition_variable m_inputSynchronizer;
std::mutex m_inputMutex;
std::unordered_map<long, bool> m_results;
std::condition_variable m_outputSynchronizer;
std::mutex m_outputMutex;
// This is synchronized with inputMutex
bool m_shouldTerminate;
std::vector<bool> m_terminateCounter;
unsigned m_poolSize;
int computeIK(WorkerTaskData& task);
void computeJointVelocities(WorkerTaskData& task, iDynTree::Twist& relativeVelocity);
void worker();
public:
IKWorkerPool(int size,
std::vector<LinkPairInfo> &linkPairs,
std::vector<SegmentInfo> &segments);
~IKWorkerPool();
/*!
* Perform a "full" run of the implemented operations.
* Currently: IK and joint velocities computation
* @note this function is blocking
* @note as this function does not perform a copy of the objects
* it assumes nobody touches the objects.
*/
void runAndWait();
int closeIKWorkerPool();
};
#endif // IKWORKERPOOL_H