45 environment.
getController()->getAvailableSignals(signal_target);
55 environment.
getPlant()->getAvailableSignals(signal_target);
62 environment.
getObserver()->getAvailableSignals(signal_target);
88 PRINT_ERROR(
"ClosedLoopControlTask::performTask(): dt <= 0 selected, but current controller does not support asynchronous control.");
101 using ControlVector = Eigen::VectorXd;
102 using StateVector = Eigen::VectorXd;
103 using OutputVector = Eigen::VectorXd;
115 if (!
verify(environment, msg))
return;
138 Time compensator_meas_start;
147 std::vector<std::pair<double, Eigen::VectorXd>> useq_predict;
153 while (t <= tf &&
ok())
170 if (!plant->
output(
y, t, signal_target, ns))
PRINT_ERROR(
"ClosedLoopControl::performTask(): error while retreiving plant output.");
178 if (!observer->
observe(
y,
x, last_dt, t, signal_target, ns))
PRINT_ERROR(
"ClosedLoopControl::performTask(): observer error.");
199 if (!controller->
step(
x, *
_xreference, *
_ureference, last_dt, t, u_sequence, x_sequence, signal_target,
nullptr,
nullptr,
nullptr, ns))
201 PRINT_ERROR(
"ClosedLoopControl::performTask(): controller error.");
219 "ClosedLoopControl::performTask(): asychnronous control mode: controller returned dt>_max_dt. Setting dt=dt_max. This " 220 "warning is printed once.");
227 "ClosedLoopControl::performTask(): asychnronous control mode: controller returned dt<_min_dt. Setting dt=dt_min. This warning is " 235 plant->
control(u_sequence, x_sequence, dt, t, signal_target, ns);
243 cpu_time =
Time::now() - compensator_meas_start;
244 cpu_time_cache = cpu_time;
255 if (u_sequence && !u_sequence->isEmpty()) signal_target->
sendMeasurement(ns +
"control_input", t.
toSec(), u_sequence->getValuesMap(0));
272 if (msg) msg->clear();
278 if (msg) *msg +=
"State reference trajectory not specified for ClosedLoopControlTask\n";
285 if (msg) *msg +=
"Control reference trajectory not specified for ClosedLoopControlTask\n";
289 std::string environment_msg;
290 ret_val = ret_val && environment.
verify(&environment_msg);
291 if (msg) *msg += environment_msg;
292 if (ret_val ==
false)
return false;
299 *msg +=
"State reference trajectory dimension (" + std::to_string(
_xreference->getDimension()) +
300 ") does not match controller state dimension (" + std::to_string(environment.
getController()->getStateDimension()) +
").\n";
306 *msg +=
"Control reference trajectory dimension (" + std::to_string(
_ureference->getDimension()) +
307 ") does not match controller control input dimension (" +
308 std::to_string(environment.
getController()->getControlInputDimension()) +
").\n";
311 if (environment.
getPlant()->requiresFutureControls() && !environment.
getController()->providesFutureControls())
314 if (msg) *msg +=
"Controller does not support control sequences, that are required by the plant";
317 if (environment.
getPlant()->requiresFutureStates() && !environment.
getController()->providesFutureStates())
320 if (msg) *msg +=
"Controller does not support state sequences, that are required by the plant";
332 #ifdef MESSAGE_SUPPORT 333 void ClosedLoopControlTask::toMessage(corbo::messages::ClosedLoopControlTask& message)
const 351 void ClosedLoopControlTask::fromMessage(
const corbo::messages::ClosedLoopControlTask& message, std::stringstream* issues)
362 if (message.has_xreference())
366 if (util::get_oneof_field_type(message.xreference(),
"reference", type,
false))
372 xreference->fromMessage(message.xreference(), issues);
380 if (message.has_ureference())
384 if (util::get_oneof_field_type(message.ureference(),
"reference", type,
false))
390 ureference->fromMessage(message.ureference(), issues);
401 _compensator.fromMessage(message.compensator(), issues);
405 if (message.has_computation_delay_filter() && !message.computation_delay_filter().has_no_filter())
409 if (util::get_oneof_field_type(message.computation_delay_filter(),
"filter", type,
false))
415 filter->fromMessage(message.computation_delay_filter(), issues);
virtual double getControlDuration() const
Return the duration for which the control u obtained from step() is valid (useful for asynchronous co...
bool initialize()
initialize the predictor
TimeValueBuffer _time_value_buffer
void appendValues(double t, const Eigen::Ref< const Eigen::VectorXd > &u)
#define PRINT_WARNING_ONCE(msg)
Print msg-stream only once.
Standard environment for control tasks.
void predict(const Eigen::Ref< const StateVector > &x0, std::vector< std::pair< double, ControlVector >> u_seq, double dt, Eigen::Ref< StateVector > x1)
Predict x1 using t0, x0, u and dt (alias between x0 and x1 allowed)
Duration lastCycleTime() const
Return actual execution time of the last cycle.
ReferenceTrajectoryInterface::Ptr _xreference
#define PRINT_WARNING(msg)
Print msg-stream.
static Time now()
Retrieve current system time.
FilterInterface::Ptr _computation_delay_filter
std::shared_ptr< FilterInterface > Ptr
virtual void sendSignals(double t, SignalTargetInterface &signal_target, const std::string &ns="") const
void fromSec(double t)
Set duration from seconds (see Duration(double t))
void setControlReference(ReferenceTrajectoryInterface::Ptr ureference)
Set control input reference trajectory.
virtual void stop()
Stop plant (you might probably use this to set the plant into a safe setpoint)
virtual bool step(const StateVector &x, ReferenceTrajectoryInterface &xref, ReferenceTrajectoryInterface &uref, const Duration &dt, const Time &t, ControlVector &u, SignalTargetInterface *signal_target=nullptr, const std::string &ns="")
Perform actual controller step / control law computation.
virtual void sendMeasurement(Measurement::ConstPtr measurement)=0
Send a measurement to the target.
Interface class for signal targets.
Representation of time stamps.
void performTask(Environment &environment, SignalTargetInterface *signal_target=nullptr, std::string *msg=nullptr, const std::string &ns="") override
Perform task.
virtual bool observe(const OutputVector &y, StateVector &x, const Duration &dt, const Time &t, SignalTargetInterface *signal_target=nullptr, const std::string &ns="")=0
Perform actual observer step / state estimation.
void setStateReference(ReferenceTrajectoryInterface::Ptr xreference)
Set state reference trajectory.
void getAvailableSignals(const Environment &environment, SignalTargetInterface &signal_target, const std::string &ns="") const override
Retrieve available signals from the task.
Interface class for observers.
const PlantInterface::Ptr & getPlant() const
Read access to the underlying plant.
virtual void registerMeasurement(const std::string &unique_name, int value_dimension, const std::vector< std::string > &value_labels={}, bool zero_order_hold=false)=0
Register a measurement type at current target.
Rate objects can be used to run loops at a desired rate.
bool verify(std::string *msg=nullptr) const
Check if the environment satisfies all requirements (dimensions, ...)
virtual int getStateDimension() const =0
Return the dimension of the required plant state/output.
bool verify(const Environment &environment, std::string *msg=nullptr) const override
Check if the environment and other settings satisfy all requirements for the given task...
void reset()
Reset internal buffer.
bool sleep()
Sleep for the remaining duration to met the desired frequency (w.r.t previous sleep call) ...
static Factory & instance()
< Retrieve static instance of the factory
const ObserverInterface::Ptr & getObserver() const
Read access to the underlying observer.
OneStepPredictor _compensator
virtual int getControlInputDimension() const =0
Return the control input dimension.
void reset() override
Reset task state.
double toSec() const
Return duration in seconds.
constexpr const int INHERITED
Inherit property.
double _computation_delay
virtual bool initialize()
Initialize plant.
bool _compensate_dead_time
double toSec() const
Cast time stamp to seconds.
virtual int getOutputDimension() const =0
Return the plant output dimension (y)
virtual bool control(const ControlVector &u, const Duration &dt, const Time &t, SignalTargetInterface *signal_target=nullptr, const std::string &ns="")
Send commands to plant.
bool ok()
global method to check whether to proceed or cancel the current action
std::shared_ptr< ReferenceTrajectoryInterface > Ptr
void fromSec(double t)
Set time stamp from seconds.
void updateCycleTime(const Duration &dt)
Update cycle time without resetting start time.
Interface class for controllers.
std::shared_ptr< TimeSeries > Ptr
virtual bool output(OutputVector &output, const Time &t, SignalTargetInterface *signal_target=nullptr, const std::string &ns="")=0
Retrieve current plant output (measurements)
ReferenceTrajectoryInterface::Ptr _ureference
virtual bool initialize(const StateVector &x, ReferenceTrajectoryInterface &expected_xref, ReferenceTrajectoryInterface &expected_uref, const Duration &expected_dt, const Time &t, ReferenceTrajectoryInterface *expected_sref=nullptr)
Initialize the controller.
std::shared_ptr< Derived > create(const std::string &name, bool print_error=true) const
Create a shared instance of the desired object.
void getValues(double ts, double dt, std::vector< std::pair< double, Eigen::VectorXd >> &useq_out)
Compute the delayed values.
The matrix class, also used for vectors and row-vectors.
const ControllerInterface::Ptr & getController() const
Read access to the underlying controller.
ClosedLoopControlTask()
Default constructor.
Representation of time durations.
void setInitialValue(const Eigen::Ref< const Eigen::VectorXd > &uinit)
Specify initial value.
bool _compensate_cpu_time
Interface class for plants.
#define PRINT_ERROR(msg)
Print msg-stream as error msg.