Aikido
KinematicSimulationJointCommandExecutor-impl.hpp
Go to the documentation of this file.
1 #include <dart/common/Console.hpp>
2 
4 
5 namespace aikido {
6 namespace control {
7 
8 //==============================================================================
9 extern template class KinematicSimulationJointCommandExecutor<
11 
12 extern template class KinematicSimulationJointCommandExecutor<
14 
15 extern template class KinematicSimulationJointCommandExecutor<
17 
18 //==============================================================================
19 template <ExecutorType T>
22  ::dart::dynamics::MetaSkeletonPtr metaskeleton)
24  checkNull(metaskeleton)->getDofs(),
26  , mInProgress{false}
27  , mPromise{nullptr}
28  , mMutex{}
29 {
30 }
31 
32 template <ExecutorType T>
35  std::vector<::dart::dynamics::DegreeOfFreedom*> dofs)
37  , mInProgress{false}
38  , mPromise{nullptr}
39  , mMutex{}
40 {
41 }
42 
43 //==============================================================================
44 template <ExecutorType T>
45 KinematicSimulationJointCommandExecutor<
46  T>::~KinematicSimulationJointCommandExecutor()
47 {
48  {
49  std::lock_guard<std::mutex> lock(mMutex);
50  DART_UNUSED(lock); // Suppress unused variable warning
51 
52  if (mInProgress)
53  {
54  mInProgress = false;
55  mPromise->set_exception(
56  std::make_exception_ptr(std::runtime_error("Command canceled.")));
57  }
58  this->stop();
59  }
60 }
61 
62 //==============================================================================
63 template <ExecutorType T>
65  const std::vector<double>& command,
66  const std::chrono::duration<double>& timeout,
67  const std::chrono::system_clock::time_point& timepoint)
68 {
69  auto promise = std::promise<int>();
70 
71  if (command.size() != this->mDofs.size())
72  {
73  promise.set_exception(std::make_exception_ptr(
74  std::runtime_error("DOF of command does not match DOF of joints.")));
75  return promise.get_future();
76  }
77 
78  std::lock_guard<std::mutex> lock(mMutex);
79  DART_UNUSED(lock); // Suppress unused variable warning
80  if (mInProgress)
81  {
82  // Overwrite previous command
83  mCommand.clear();
84  mPromise->set_exception(
85  std::make_exception_ptr(std::runtime_error("Command canceled.")));
86  }
87 
88  mPromise.reset(new std::promise<int>());
89 
90  mCommand = command;
91  mInProgress = true;
92  mExecutionStartTime = timepoint;
93  mTimeout = timeout;
94 
95  // Set start positions
96  mStartPosition.clear();
97  for (std::size_t i = 0; i < this->mDofs.size(); ++i)
98  {
99  auto dof = this->mDofs[i];
100  mStartPosition.push_back(dof->getPosition());
101  }
102  switch (T)
103  {
105  dtwarn << "[KinematicSimulationEffortExecutor::execute] No Dynamics; "
106  << "executor will mimic velocity behavior.\n";
108 
109  for (std::size_t i = 0; i < this->mDofs.size(); ++i)
110  {
111  auto dof = this->mDofs[i];
112  dof->setVelocity(command[i]);
113  }
114 
115  break;
116 
118 
119  for (std::size_t i = 0; i < this->mDofs.size(); ++i)
120  {
121  auto dof = this->mDofs[i];
122  if (mTimeout.count() > 0.0)
123  {
124  dof->setVelocity((command[i] - mStartPosition[i]) / timeout.count());
125  }
126  }
127 
128  break;
129 
130  default:
131  // Other Executors not implemented
132  mCommand.clear();
133  mPromise->set_exception(std::make_exception_ptr(
134  std::logic_error("Executor not implemented")));
135  mInProgress = false;
136  }
137 
138  return mPromise->get_future();
139 }
140 
141 //==============================================================================
142 template <ExecutorType T>
144  const std::chrono::system_clock::time_point& timepoint)
145 {
146  std::lock_guard<std::mutex> lock(mMutex);
147 
148  if (!mInProgress)
149  return;
150 
151  const auto timeSinceBeginning = timepoint - mExecutionStartTime;
152  const auto executionTime
153  = std::chrono::duration<double>(timeSinceBeginning).count();
154 
155  // executionTime may be negative if the thread calling \c step is queued
156  // before and dequeued after \c execute is called.
157  if (executionTime < 0)
158  return;
159 
160  // Set joint states
161  switch (T)
162  {
164  case ExecutorType::VELOCITY: {
165  for (size_t i = 0; i < this->mDofs.size(); ++i)
166  {
167  auto dof = this->mDofs[i];
168  dof->setPosition(mStartPosition[i] + executionTime * mCommand[i]);
169  }
170 
171  break;
172  }
173  case ExecutorType::POSITION: {
174  // Instantaneous movement if no timeout.
175  double interpTime
176  = (mTimeout.count() == 0) ? 1.0 : executionTime / mTimeout.count();
177  // Stop at the correct position
178  if (interpTime > 1.0)
179  {
180  interpTime = 1.0;
181  }
182 
183  for (size_t i = 0; i < this->mDofs.size(); ++i)
184  {
185  auto dof = this->mDofs[i];
186  double pose
187  = (1.0 - interpTime) * mStartPosition[i] + interpTime * mCommand[i];
188  dof->setPosition(pose);
189  }
190 
191  break;
192  }
193  default:
194  throw std::logic_error(
195  "Other KinematicSimulationExecutors not implemented.");
196  }
197 
198  // Check if command has timed out
199  if (mTimeout.count() > 0.0 && executionTime >= mTimeout.count())
200  {
201  mCommand.clear();
202  mInProgress = false;
203  mPromise->set_value(0);
204  }
205 }
206 
207 //==============================================================================
208 template <ExecutorType T>
210 {
211  std::lock_guard<std::mutex> lock(mMutex);
212 
213  if (mInProgress)
214  {
215  mCommand.clear();
216  mInProgress = false;
217  mPromise->set_exception(
218  std::make_exception_ptr(std::runtime_error("Command canceled.")));
219  }
220  else
221  {
222  dtwarn << "[KinematicSimulationJointCommandExecutor::cancel] Attempting to "
223  << "cancel command, but no command in progress.\n";
224  }
225 }
226 
227 } // namespace control
228 } // namespace aikido
aikido::control::JointCommandExecutor
Abstract class for executing a command of a single type on a group of joints.
Definition: JointCommandExecutor.hpp:21
aikido::control::ExecutorType::VELOCITY
@ VELOCITY
aikido
Format of serialized trajectory in YAML.
Definition: algorithm.hpp:4
memory.hpp
aikido::control::ExecutorType::POSITION
@ POSITION
aikido::control::ExecutorType::STATE
@ STATE
aikido::control::KinematicSimulationJointCommandExecutor::execute
virtual std::future< int > execute(const std::vector< double > &command, const std::chrono::duration< double > &timeout, const std::chrono::system_clock::time_point &timepoint) override
Execute a Joint Command, setting future upon completion.
Definition: KinematicSimulationJointCommandExecutor-impl.hpp:64
aikido::control::KinematicSimulationJointCommandExecutor::cancel
void cancel() override
Cancels the current command.
Definition: KinematicSimulationJointCommandExecutor-impl.hpp:209
aikido::control::checkNull
T checkNull(T obj)
Check if Ptr is null Useful for initializer Lists.
Definition: util.hpp:41
aikido::control::KinematicSimulationJointCommandExecutor::step
void step(const std::chrono::system_clock::time_point &timepoint) override
Step to a point in time.
Definition: KinematicSimulationJointCommandExecutor-impl.hpp:143
aikido::control::ExecutorType::EFFORT
@ EFFORT
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::KinematicSimulationJointCommandExecutor::KinematicSimulationJointCommandExecutor
KinematicSimulationJointCommandExecutor(::dart::dynamics::MetaSkeletonPtr metaskeleton)
Constructor.
Definition: KinematicSimulationJointCommandExecutor-impl.hpp:21