WholeBodyTrajectoryController.h
Go to the documentation of this file.
1 /**
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @author Fabian Reister (fabian dot reister at kit dot edu)
17  * @date 2024
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
22 #pragma once
23 
24 #include <cstddef>
25 #include <mutex>
26 #include <vector>
27 
28 #include <VirtualRobot/VirtualRobot.h>
29 
33 
41 
42 #include <armarx/control/interface/ConfigurableNJointControllerInterface.h>
44 #include <armarx/control/njoint_controller/joint_space/aron/WholeBodyTrajectoryControllerConfig.aron.generated.h>
45 
46 namespace armarx
47 {
48  class ControlTargetHolonomicPlatformVelocity;
49  class SensorValueHolonomicPlatformWithAbsolutePosition;
50 } // namespace armarx
51 
53 {
54  struct Target
55  {
56  };
57 
58  class Trajectory
59  {
60  public:
61  using TrajectoryPoint = armarx::control::njoint_controller::joint_space::
62  whole_body_trajectory_controller::arondto::TrajectoryPoint;
63 
64  using TimestampUS = std::int64_t;
65 
66  Trajectory(const std::vector<TrajectoryPoint>& traj) : trajectory_(traj)
67  {
68  }
69 
70  const TrajectoryPoint&
71  initialPoint() const
72  {
73  return trajectory_.front();
74  }
75 
76  void
77  setStartTime(const TimestampUS& timestamp)
78  {
79  startTimestampUS_ = timestamp;
80  }
81 
82  struct TimeInterval
83  {
84  TimestampUS min; // [s]
85  TimestampUS max; // [s]
86 
87  bool
88  isWithin(const TimestampUS timestamp) const
89  {
90  return timestamp >= min and timestamp <= max;
91  }
92  };
93 
94  std::optional<TrajectoryPoint>
95  at(const TimestampUS& timestamp)
96  {
97  ARMARX_CHECK_NOT_NULL(startTimestampUS_);
98 
99  // check if timestamp is in range
100  if (not timeBounds().isWithin(timestamp))
101  {
102  if (timestamp <= timeBounds().min)
103  {
104  return trajectory_.front();
105  }
106 
107  if (timestamp >= timeBounds().max)
108  {
109  return trajectory_.back();
110  }
111 
112  ARMARX_WARNING << "Should not get here!";
113  return std::nullopt;
114  }
115 
116  // relative timestamp wrt to start of trajectory
117  const TimestampUS relativeTimeUS = timestamp - startTimestampUS_.value();
118 
119  // we assume that our trajectory is sorted (monotonically increasing timestamps)
120 
121  // we identify the first element which is timewise after the current time
122 
123  const auto compareFn = [](const TrajectoryPoint& lhs, const TimestampUS& val) -> bool
124  { return lhs.timestampMicroSeconds < val; };
125 
126  const auto it =
127  std::lower_bound(trajectory_.begin(), trajectory_.end(), relativeTimeUS, compareFn);
128 
129  // if match is first element, return it without interpolation
130  if (it == trajectory_.begin())
131  {
132  return *it;
133  }
134 
135  const auto itBefore = std::prev(it);
136 
137  // interpolation factor [0,1]
138  const double f = static_cast<double>(relativeTimeUS - itBefore->timestampMicroSeconds) /
139  (it->timestampMicroSeconds - itBefore->timestampMicroSeconds);
140 
141 
142  const auto linearInterpolate = [](const std::vector<double>& a,
143  const std::vector<double>& b,
144  const double f) -> std::vector<double>
145  {
146  // FIXME consider 2 pi bounds
147  ARMARX_CHECK_EQUAL(a.size(), b.size());
150 
151  const std::size_t n = a.size();
152 
153  std::vector<double> c(n);
154 
155  for (std::size_t i = 0; i < n; i++)
156  {
157  c.at(i) = (1 - f) * a.at(i) + f * b.at(i);
158  }
159 
160  return c;
161  };
162 
163  // const auto noInterpolate = [](const std::vector<double>& a,
164  // const std::vector<double>& b,
165  // const double f) -> std::vector<double> { return b; };
166 
167 
168  TrajectoryPoint tp;
169  tp.timestampMicroSeconds = timestamp;
170  tp.jointValues = linearInterpolate(itBefore->jointValues, it->jointValues, f);
171  tp.jointValuesPlatform =
172  linearInterpolate(itBefore->jointValuesPlatform, it->jointValuesPlatform, f);
173  tp.handJointValues =
174  linearInterpolate(itBefore->handJointValues, it->handJointValues, f);
175 
176  tp.jointVelocities =
177  linearInterpolate(itBefore->jointVelocities, it->jointVelocities, f);
178  tp.jointVelocitiesPlatform = linearInterpolate(
179  itBefore->jointVelocitiesPlatform, it->jointVelocitiesPlatform, f);
180 
181 
182  return tp;
183  }
184 
185  bool
186  isValid(const TimestampUS& timestamp) const
187  {
188  ARMARX_CHECK_NOT_NULL(startTimestampUS_);
189 
190  return timeBounds().isWithin(timestamp);
191  }
192 
193  TimeInterval
194  timeBounds() const
195  {
196  ARMARX_CHECK_NOT_NULL(startTimestampUS_);
197 
198  return {.min = trajectory_.front().timestampMicroSeconds + startTimestampUS_.value(),
199  .max = trajectory_.back().timestampMicroSeconds + startTimestampUS_.value()};
200  }
201 
202  protected:
203  private:
204  const std::vector<armarx::control::njoint_controller::joint_space::
205  whole_body_trajectory_controller::arondto::TrajectoryPoint>
206  trajectory_;
207 
208  std::optional<std::int64_t> startTimestampUS_;
209  };
210 
211  struct DebugData
212  {
213  std::int64_t localTimestamp;
214 
217 
218  std::vector<float> jointPosDiff;
219 
220  arondto::TrajectoryPoint targetState;
221 
222  Eigen::Isometry3f currentTcpPose;
223  Eigen::Isometry3f currentPlatformPose;
224 
226  };
227 
228  class Controller :
229  virtual public NJointControllerWithTripleBuffer<Target>,
230  virtual public core::ConfigurableNJointControllerBase<arondto::Config>
231  {
232  public:
233  Controller(const RobotUnitPtr& robotUnit,
234  const NJointControllerConfigPtr& config,
235  const VirtualRobot::RobotPtr& robot);
236 
237 
238  std::string getClassName(const Ice::Current& iceCurrent = Ice::emptyCurrent) const override;
239 
240  void rtRun(const IceUtil::Time& sensorValuesTimestamp,
241  const IceUtil::Time& timeSinceLastIteration) override;
242 
243 
244  void onPublish(const SensorAndControl&,
246  const DebugObserverInterfacePrx&) override;
247 
248 
249  protected:
250  void rtPreActivateController() override;
251 
252  virtual void onDisconnectNJointController();
253 
254  void
256  {
257  // NYI
258  }
259 
260  private:
261  struct ControlTargets
262  {
264  std::vector<ControlTarget1DoFActuatorVelocity*> jointTargets;
265  std::vector<ControlTarget1DoFActuatorPosition*> handTargets;
266  } controlTargets_;
267 
268  const GlobalRobotLocalizationSensorDevice::SensorValueType* svGlobalRobotLocalization_;
269  std::vector<const SensorValue1DoFActuatorPosition*> jointSensorValues_;
270 
271 
272  std::optional<Trajectory> trajectory_;
273 
274  // std::size_t trajIdx_ = 0;
275 
276  MultiDimPIDController pidPlatform_;
277  PIDController opidPlatform_;
278 
279  std::optional<MultiDimPIDController> pidArm_;
280 
281  std::vector<std::string> jointNames_;
282  std::vector<std::string> fingerJointNames_;
283 
284  VirtualRobot::RobotPtr robot_;
285  VirtualRobot::RobotNodePtr rtTcpNode_;
286 
287  VirtualRobot::RobotPtr debugRobot_;
288  VirtualRobot::RobotNodePtr publishTcpNode_;
289 
290 
291  TripleBuffer<DebugData> bufferRtToOnPublish_;
292 
293 
294  std::vector<DebugData> whatever_;
295  std::atomic_bool whateverFlag_ = true;
296  };
297 
298 } // namespace armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller
armarx::SensorValueGlobalRobotPose
Definition: GlobalRobotPoseSensorDevice.h:41
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::currentPlatformPose
Eigen::Isometry3f currentPlatformPose
Definition: WholeBodyTrajectoryController.h:223
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::initialPoint
const TrajectoryPoint & initialPoint() const
Definition: WholeBodyTrajectoryController.h:71
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::onDisconnectNJointController
virtual void onDisconnectNJointController()
Definition: WholeBodyTrajectoryController.cpp:608
armarx::ControlTargetHolonomicPlatformVelocity
Brief description of class ControlTargetHolonomicPlatformVelocity.
Definition: ControlTargetHolonomicPlatformVelocity.h:38
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::at
std::optional< TrajectoryPoint > at(const TimestampUS &timestamp)
Definition: WholeBodyTrajectoryController.h:95
NJointControllerWithTripleBuffer.h
SensorValueHolonomicPlatform.h
armarx::NJointControllerWithTripleBuffer
Definition: NJointControllerWithTripleBuffer.h:10
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::getClassName
std::string getClassName(const Ice::Current &iceCurrent=Ice::emptyCurrent) const override
Definition: WholeBodyTrajectoryController.cpp:223
RobotUnit.h
armarx::control::njoint_controller::core::ConfigurableNJointControllerBase
Definition: ConfigurableNJointControllerBase.h:33
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::currentTcpPose
Eigen::Isometry3f currentTcpPose
Definition: WholeBodyTrajectoryController.h:222
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::isControllerActive
bool isControllerActive
Definition: WholeBodyTrajectoryController.h:225
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::updateConfig
void updateConfig(const ConfigurableNJointControllerBaseT::AronConfigT &configData) override
Definition: WholeBodyTrajectoryController.h:255
armarx::MultiDimPIDControllerTemplate<>
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::setStartTime
void setStartTime(const TimestampUS &timestamp)
Definition: WholeBodyTrajectoryController.h:77
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::TimestampUS
std::int64_t TimestampUS
Definition: WholeBodyTrajectoryController.h:64
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::platformPosDiff
float platformPosDiff
Definition: WholeBodyTrajectoryController.h:215
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:267
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller
This file is part of ArmarX.
Definition: WholeBodyTrajectoryController.cpp:53
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::TimeInterval
Definition: WholeBodyTrajectoryController.h:82
armarx::control::njoint_controller::core::ConfigurableNJointControllerBase::AronConfigT
_AronConfigT AronConfigT
Definition: ConfigurableNJointControllerBase.h:37
ConfigurableNJointControllerBase.h
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::rtRun
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
Definition: WholeBodyTrajectoryController.cpp:230
armarx::detail::ControlThreadOutputBufferEntry
Definition: ControlThreadOutputBuffer.h:177
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Target
Definition: WholeBodyTrajectoryController.h:54
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::timeBounds
TimeInterval timeBounds() const
Definition: WholeBodyTrajectoryController.h:194
MultiDimPIDController.h
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::isValid
bool isValid(const TimestampUS &timestamp) const
Definition: WholeBodyTrajectoryController.h:186
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::TrajectoryPoint
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::arondto::TrajectoryPoint TrajectoryPoint
Definition: WholeBodyTrajectoryController.h:62
armarx::PIDController
Definition: PIDController.h:43
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::onPublish
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
Definition: WholeBodyTrajectoryController.cpp:469
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller
Definition: WholeBodyTrajectoryController.h:228
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::jointPosDiff
std::vector< float > jointPosDiff
Definition: WholeBodyTrajectoryController.h:218
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData
Definition: WholeBodyTrajectoryController.h:211
ControlTarget1DoFActuator.h
ARMARX_CHECK_GREATER_EQUAL
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
Definition: ExpressionException.h:123
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
ARMARX_CHECK_LESS_EQUAL
#define ARMARX_CHECK_LESS_EQUAL(lhs, rhs)
This macro evaluates whether lhs is less or equal (<=) rhs and if it turns out to be false it will th...
Definition: ExpressionException.h:109
ExpressionException.h
PIDController.h
TripleBuffer.h
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::Trajectory
Trajectory(const std::vector< TrajectoryPoint > &traj)
Definition: WholeBodyTrajectoryController.h:66
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::TimeInterval::isWithin
bool isWithin(const TimestampUS timestamp) const
Definition: WholeBodyTrajectoryController.h:88
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::Controller
Controller(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
Definition: WholeBodyTrajectoryController.cpp:59
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::TimeInterval::max
TimestampUS max
Definition: WholeBodyTrajectoryController.h:85
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::localTimestamp
std::int64_t localTimestamp
Definition: WholeBodyTrajectoryController.h:213
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::platformOriDiff
float platformOriDiff
Definition: WholeBodyTrajectoryController.h:216
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:294
IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface >
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory
Definition: WholeBodyTrajectoryController.h:58
Logging.h
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::DebugData::targetState
arondto::TrajectoryPoint targetState
Definition: WholeBodyTrajectoryController.h:220
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Controller::rtPreActivateController
void rtPreActivateController() override
This function is called before the controller is activated.
Definition: WholeBodyTrajectoryController.cpp:456
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
SensorValue1DoFActuator.h
armarx::control::njoint_controller::joint_space::whole_body_trajectory_controller::Trajectory::TimeInterval::min
TimestampUS min
Definition: WholeBodyTrajectoryController.h:84
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::TripleBuffer< DebugData >