Aikido
JacobianExecutor-impl.hpp
Go to the documentation of this file.
1 #include <Eigen/Dense>
2 #include <dart/common/Console.hpp>
3 #include <dart/dynamics/dynamics.hpp>
4 
8 
9 namespace aikido {
10 namespace control {
11 
12 //==============================================================================
13 extern template class JacobianExecutor<ExecutorType::VELOCITY>;
14 
15 extern template class JacobianExecutor<ExecutorType::EFFORT>;
16 
17 //==============================================================================
18 template <ExecutorType T>
20  ::dart::dynamics::BodyNode* eeNode,
21  std::shared_ptr<JointCommandExecutor<T>> executor,
22  double lambda)
24  executor ? executor->getDofs() : checkNull(eeNode)->getDependentDofs(),
25  executor ? executor->getTypes()
26  : std::set<ExecutorType>{T, ExecutorType::STATE})
27  , mEENode{checkNull(eeNode)}
28  , mExecutor{executor}
29  , mLambda{lambda}
30  , mInProgress{false}
31  , mPromise{nullptr}
32  , mMutex{}
33 {
34  if (!mExecutor)
35  {
36  this->releaseDofs();
37  // Null executor, create as KinematicSimulationJointCommandExecutor
38  mExecutor = std::make_shared<KinematicSimulationJointCommandExecutor<T>>(
39  mEENode->getDependentDofs());
40  }
41 
42  // Release sub-executor DoFs, this class owns them now
43  mExecutor->releaseDofs();
44 }
45 
46 //==============================================================================
47 template <ExecutorType T>
49 {
50  {
51  std::lock_guard<std::mutex> lock(mMutex);
52  DART_UNUSED(lock); // Suppress unused variable warning
53 
54  if (mInProgress)
55  {
56  mInProgress = false;
57  mPromise->set_exception(
58  std::make_exception_ptr(std::runtime_error("Command canceled.")));
59  }
60  mExecutor->stop();
61  this->stop();
62  }
63 }
64 
65 //==============================================================================
66 template <ExecutorType T>
68  const Eigen::Vector6d command,
69  const std::chrono::duration<double>& timeout,
70  const std::chrono::system_clock::time_point& timepoint)
71 {
72 
73  {
74  std::lock_guard<std::mutex> lock(mMutex);
75  DART_UNUSED(lock); // Suppress unused variable warning
76 
77  if (mInProgress)
78  {
79  // Overwrite previous velocity command
80  mCommand = Eigen::Vector6d::Zero();
81  mPromise->set_exception(
82  std::make_exception_ptr(std::runtime_error("Command canceled.")));
83  }
84 
85  mPromise.reset(new std::promise<int>());
86 
87  mCommand = command;
88  mExecutionStartTime = timepoint;
89  mTimeout = timeout;
90  mFuture = mExecutor->execute(SE3ToJoint(mCommand), mTimeout, timepoint);
91  mInProgress = true;
92  }
93 
94  return mPromise->get_future();
95 }
96 
97 //==============================================================================
98 template <ExecutorType T>
99 std::vector<double> JacobianExecutor<T>::SE3ToJoint(
100  const Eigen::Vector6d command)
101 {
102 
103  // Command value (as Eigen)
104  Eigen::Vector6d refCmd = command;
105  // Return value (as Eigen)
106  Eigen::VectorXd jointCmd(this->mDofs.size());
107  jointCmd.setZero();
108 
109  if (refCmd.norm() != 0)
110  {
111  // Get Jacobian relative only to controlled joints
112  Eigen::MatrixXd fullJ = mEENode->getWorldJacobian();
113  Eigen::MatrixXd J(SE3_SIZE, this->mDofs.size());
114  auto fullDofs = mEENode->getDependentDofs();
115  for (size_t fullIndex = 0; fullIndex < fullDofs.size(); fullIndex++)
116  {
117  auto it = std::find(
118  this->mDofs.begin(), this->mDofs.end(), fullDofs[fullIndex]);
119  if (it != this->mDofs.end())
120  {
121  int index = it - this->mDofs.begin();
122  J.col(index) = fullJ.col(fullIndex);
123  }
124  }
125 
126  // Calculate joint command
127  Eigen::MatrixXd JtJ = J.transpose() * J;
128  JtJ += mLambda * mLambda
129  * Eigen::MatrixXd::Identity(JtJ.rows(), JtJ.cols());
130  jointCmd = JtJ.inverse() * J.transpose() * refCmd;
131  }
132 
133  return std::vector<double>(
134  jointCmd.data(), jointCmd.data() + jointCmd.size());
135 }
136 
137 //==============================================================================
138 template <ExecutorType T>
140  const std::chrono::system_clock::time_point& timepoint)
141 {
142  std::lock_guard<std::mutex> lock(mMutex);
143  mExecutor->step(timepoint);
144 
145  if (!mInProgress)
146  return;
147 
148  // Check that underlying velocity command hasn't errored
149  auto status = mFuture.wait_for(std::chrono::milliseconds(1));
150  if (status == std::future_status::ready)
151  {
152  bool fail = false;
153  try
154  {
155  int result = mFuture.get();
156  if (result)
157  {
158  fail = true;
159  mPromise->set_value(result);
160  }
161  }
162  catch (const std::exception& e)
163  {
164  fail = true;
165  mPromise->set_exception(std::current_exception());
166  }
167  if (fail)
168  {
169  mCommand = Eigen::Vector6d::Zero();
170  mExecutor->cancel();
171  mInProgress = false;
172  return;
173  }
174  }
175 
176  const auto timeSinceBeginning = timepoint - mExecutionStartTime;
177  const auto executionTime
178  = std::chrono::duration<double>(timeSinceBeginning).count();
179 
180  // executionTime may be negative if the thread calling \c step is queued
181  // before and dequeued after \c execute is called.
182  if (executionTime < 0)
183  return;
184 
185  // Check if command has timed out
186  if (mTimeout.count() > 0.0 && executionTime >= mTimeout.count())
187  {
188  mCommand = Eigen::Vector6d::Zero();
189  mExecutor->cancel();
190  mInProgress = false;
191  mPromise->set_value(0);
192  }
193 
194  // Update underlying velocity command
195  mFuture = mExecutor->execute(SE3ToJoint(mCommand), mTimeout, timepoint);
196  mExecutor->step(timepoint);
197 }
198 
199 //==============================================================================
200 template <ExecutorType T>
202  const std::vector<double>& command,
203  const std::chrono::duration<double>& timeout,
204  const std::chrono::system_clock::time_point& timepoint)
205 {
206  if (mInProgress)
207  {
208  this->cancel();
209  }
210 
211  return mExecutor->execute(command, timeout, timepoint);
212 }
213 
214 //==============================================================================
215 template <ExecutorType T>
217 {
218  std::lock_guard<std::mutex> lock(mMutex);
219  mExecutor->cancel();
220 
221  if (mInProgress)
222  {
223  mCommand = Eigen::Vector6d::Zero();
224  mInProgress = false;
225  mExecutor->cancel();
226  mPromise->set_exception(
227  std::make_exception_ptr(std::runtime_error("Command canceled.")));
228  }
229  else
230  {
231  dtwarn << "[JacobianExecutor::cancel] Attempting to "
232  << "cancel command, but no command in progress.\n";
233  }
234 }
235 
236 } // namespace control
237 } // namespace aikido
aikido::control::JointCommandExecutor
Abstract class for executing a command of a single type on a group of joints.
Definition: JointCommandExecutor.hpp:21
util.hpp
aikido::control::JacobianExecutor::~JacobianExecutor
virtual ~JacobianExecutor()
Definition: JacobianExecutor-impl.hpp:48
aikido
Format of serialized trajectory in YAML.
Definition: algorithm.hpp:4
memory.hpp
aikido::control::ExecutorType::STATE
@ STATE
aikido::control::JacobianExecutor::JacobianExecutor
JacobianExecutor(::dart::dynamics::BodyNode *eeNode, std::shared_ptr< JointCommandExecutor< T >> executor=nullptr, double lambda=DEFAULT_LAMBDA)
Constructor.
Definition: JacobianExecutor-impl.hpp:19
aikido::control::JacobianExecutor::execute
virtual std::future< int > execute(const Eigen::Vector6d command, const std::chrono::duration< double > &timeout=std::chrono::duration< double >(1))
Execute an SE3 Command, setting future upon completion.
Definition: JacobianExecutor.hpp:44
aikido::control::checkNull
T checkNull(T obj)
Check if Ptr is null Useful for initializer Lists.
Definition: util.hpp:41
aikido::control::JacobianExecutor::cancel
void cancel()
Cancels the current command.
Definition: JacobianExecutor-impl.hpp:216
aikido::control::JacobianExecutor
Executes end-effector SE3 command.
Definition: JacobianExecutor.hpp:20
KinematicSimulationJointCommandExecutor.hpp
aikido::control::ExecutorType
ExecutorType
Type of executor Can be used to determine if 2 executors make conflicting demands of individual degre...
Definition: Executor.hpp:35
aikido::control::JacobianExecutor::step
void step(const std::chrono::system_clock::time_point &timepoint) override
Step to a point in time.
Definition: JacobianExecutor-impl.hpp:139
aikido::control::JacobianExecutor::SE3ToJoint
std::vector< double > SE3ToJoint(const Eigen::Vector6d command)
Convert SE3 command to joint command.
Definition: JacobianExecutor-impl.hpp:99