25 #ifndef SRC_CORE_INCLUDE_CORBO_CORE_REFERENCE_TRAJECTORY_H_
26 #define SRC_CORE_INCLUDE_CORBO_CORE_REFERENCE_TRAJECTORY_H_
34 #ifdef MESSAGE_SUPPORT
35 #include <corbo-communication/messages/core/reference_trajectories.pb.h>
60 class ReferenceTrajectoryInterface
63 using Ptr = std::shared_ptr<ReferenceTrajectoryInterface>;
74 virtual bool isZero()
const {
return false; }
77 virtual void precompute(
double dt,
int n, Time t) = 0;
78 virtual void precompute(
const std::vector<double>& dt, Time t) = 0;
87 virtual bool isCached(
const std::vector<double>& dt,
Time t)
const = 0;
89 #ifdef MESSAGE_SUPPORT
90 virtual void toMessage(corbo::messages::ReferenceTrajectory& message)
const {}
93 virtual void fromMessage(
const corbo::messages::ReferenceTrajectory& message, std::stringstream* issues =
nullptr) {}
98 #define FACTORY_REGISTER_REFERENCE_TRAJECTORY(type) FACTORY_REGISTER_OBJECT(type, ReferenceTrajectoryInterface)
112 class StaticReference :
public ReferenceTrajectoryInterface
115 using Ptr = std::shared_ptr<StaticReference>;
122 bool isStatic()
const override {
return true; }
123 bool isZero()
const override {
return _ref.isZero(); }
126 void precompute(
double ,
int , Time )
override {}
127 void precompute(
const std::vector<double>& , Time )
override {}
138 bool isCached(
const std::vector<double>& ,
Time )
const override {
return true; }
141 #ifdef MESSAGE_SUPPORT
142 void toMessage(corbo::messages::ReferenceTrajectory& message)
const override;
143 void fromMessage(
const corbo::messages::ReferenceTrajectory& message, std::stringstream* issues =
nullptr)
override;
165 using Ptr = std::shared_ptr<ZeroReference>;
172 bool isZero()
const override {
return true; }
174 void setDimension(
int dimension) { setReference(Eigen::VectorXd::Zero(dimension)); }
176 #ifdef MESSAGE_SUPPORT
178 void toMessage(corbo::messages::ReferenceTrajectory& message)
const override;
179 void fromMessage(
const corbo::messages::ReferenceTrajectory& message, std::stringstream* issues =
nullptr)
override;
197 using Ptr = std::shared_ptr<SineReferenceTrajectory>;
201 : _amplitude(amplitude), _omega(omega), _offset(offset)
204 _cached_trajectory.resize(1);
206 getReference(t, _cached_trajectory[0]);
211 bool isStatic()
const override {
return false; }
212 bool isZero()
const override {
return false; }
213 int getDimension()
const override {
return 1; }
215 bool isCached(
double dt,
int n, Time t)
const override
217 if (_cached_dt.empty() || dt != _cached_dt[0] ||
n != _cached_trajectory.size() || t != _cached_t)
return false;
221 bool isCached(
const std::vector<double>& dt,
Time t)
const override
223 if (_cached_dt.empty() || dt.size() != _cached_dt.size() || t != _cached_t)
return false;
224 for (
int i = 0; i < dt.size(); ++i)
226 if (
std::abs(dt[i] - _cached_dt[i]) < 1e-15)
return false;
231 void precompute(
double dt,
int n,
Time t)
override
233 _cached_trajectory.resize(
n);
237 for (
int i = 0; i <
n; ++i)
240 getReference(t + d, _cached_trajectory[i]);
242 _cached_dt.resize(1);
247 void precompute(
const std::vector<double>& dt,
Time t)
override
249 _cached_trajectory.resize(dt.size() + 1);
253 getReference(t, _cached_trajectory[0]);
254 for (
int i = 0; i < dt.size(); ++i)
257 getReference(t + d, _cached_trajectory[i + 1]);
263 void getReference(
const Time& t, OutputVector& ref)
const override
266 ref(0) = _amplitude *
std::sin(_omega * t.toSec() + _offset);
271 if (k >= _cached_trajectory.size())
273 PRINT_ERROR(
"SineReferenceTrajectory::getReferenceCached: k is not a valid index for cached reference. Returning zero value");
277 return _cached_trajectory.at(k);
280 const OutputVector& getNextSteadyState(
const Time& t)
override
282 PRINT_ERROR_ONCE(
"SineReferenceTrajectory: No steady state in periodic reference. Returning zero value.");
287 void setParameters(
const double& amplitude,
const double& omega,
const double offset)
289 _amplitude = amplitude;
295 double _amplitude = 1;
298 std::vector<OutputVector> _cached_trajectory;
299 std::vector<double> _cached_dt;
301 OutputVector _zero_vector = Eigen::VectorXd::Zero(1);
303 #ifdef MESSAGE_SUPPORT
305 void toMessage(corbo::messages::ReferenceTrajectory& message)
const override;
306 void fromMessage(
const corbo::messages::ReferenceTrajectory& message, std::stringstream* issues =
nullptr)
override;
324 using Ptr = std::shared_ptr<DiscreteTimeReferenceTrajectory>;
329 setTrajectory(trajectory);
334 bool isStatic()
const override {
return _trajectory && _trajectory->getTimeDimension() == 1; }
335 bool isZero()
const override
337 if (!_trajectory || _trajectory->getValueDimension() == 0)
return false;
339 return std::all_of(_trajectory->getValues().begin(), _trajectory->getValues().end(), [](
double i) { return (i < 1e-9 && i > -1e-9); });
341 int getDimension()
const override {
return _trajectory ? _trajectory->getValueDimension() : 0; }
343 bool isCached(
double dt,
int n,
Time t)
const override
345 if (_cached_dt.empty() || dt != _cached_dt[0] ||
n != _cached_trajectory.size() || t != _cached_t)
return false;
349 bool isCached(
const std::vector<double>& dt,
Time t)
const override
351 if (_cached_dt.empty() || dt.size() != _cached_dt.size() || t != _cached_t)
return false;
352 for (
int i = 0; i < dt.size(); ++i)
354 if (
std::abs(dt[i] - _cached_dt[i]) < 1e-15)
return false;
359 void precompute(
double dt,
int n,
Time t)
override
361 _cached_trajectory.resize(
n);
365 for (
int i = 0; i <
n; ++i)
368 getReference(t + d, _cached_trajectory[i]);
370 _cached_dt.resize(1);
375 void precompute(
const std::vector<double>& dt,
Time t)
override
377 _cached_trajectory.resize(dt.size() + 1);
381 getReference(t, _cached_trajectory[0]);
382 for (
int i = 0; i < dt.size(); ++i)
385 getReference(t + d, _cached_trajectory[i + 1]);
391 void getReference(
const Time& t, OutputVector& ref)
const override
393 if (!_trajectory || _trajectory->getValueDimension() == 0)
395 PRINT_ERROR(
"DiscreteTimeReferenceTrajectory: trajectory is empty.");
399 double time = t.toSec() - _trajectory->getTimeFromStart();
401 ref.resize(_trajectory->getValueDimension());
403 if (time <= 0 || _trajectory->getTimeDimension() ==
405 ref = _trajectory->getValuesMap(0);
406 else if (time >= _trajectory->getFinalTime())
407 ref = _trajectory->getValuesMap(_trajectory->getTimeDimension() - 1);
412 const OutputVector& getReferenceCached(
int k)
const override
414 if (k >= _cached_trajectory.size())
417 "DiscreteTimeReferenceTrajectory::getReferenceCached: k is not a valid index for cached reference. Returning next steady state");
418 return _next_steady_state;
421 return _cached_trajectory[k];
424 const OutputVector& getNextSteadyState(
const Time& t)
override {
return _next_steady_state; }
428 setTrajectory(trajectory);
429 _interpolation = interpolation;
434 if (!trajectory || trajectory->getValueDimension() == 0)
436 PRINT_ERROR(
"DiscreteTimeReferenceTrajectory must be initialized with at least one point in trajectory");
440 _trajectory = trajectory;
441 _next_steady_state = trajectory->getValuesMap(trajectory->getTimeDimension() - 1);
444 _cached_trajectory.resize(1);
445 _cached_trajectory[0] = trajectory->getValuesMap(0);
448 void setTimeFromStart(
const Time& time_from_start)
450 if (_trajectory) _trajectory->setTimeFromStart(time_from_start.
toSec());
455 const TimeSeries::Ptr& getReferenceTrajectory() {
return _trajectory; }
457 #ifdef MESSAGE_SUPPORT
459 void toMessage(corbo::messages::ReferenceTrajectory& message)
const override;
460 void fromMessage(
const corbo::messages::ReferenceTrajectory& message, std::stringstream* issues =
nullptr)
override;
465 std::vector<OutputVector> _cached_trajectory;
466 std::vector<double> _cached_dt;
468 OutputVector _next_steady_state;
486 using Ptr = std::shared_ptr<BlindDiscreteTimeReferenceTrajectory>;
497 bool isZero()
const override
501 return std::all_of(
_trajectory->getValues().begin(),
_trajectory->getValues().end(), [](
double i) { return (i < 1e-9 && i > -1e-9); });
533 PRINT_ERROR(
"BlindDiscreteTimeReferenceTrajectory: trajectory is empty.");
541 if (time <= 0 || _trajectory->getTimeDimension() == 1)
561 if (!trajectory || trajectory->getValueDimension() == 0)
563 PRINT_ERROR(
"BlindDiscreteTimeReferenceTrajectory must be initialized with at least one point in trajectory");
580 #ifdef MESSAGE_SUPPORT
582 void toMessage(corbo::messages::ReferenceTrajectory& message)
const override;
583 void fromMessage(
const corbo::messages::ReferenceTrajectory& message, std::stringstream* issues =
nullptr)
override;
597 #endif // SRC_CORE_INCLUDE_CORBO_CORE_REFERENCE_TRAJECTORY_H_