MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/technological/function/MoveToPoint.cpp
2024-06-07 11:12:56 +03:00

233 lines
5.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* MoveToPoint.cpp
*
* Created on: 8 июл. 2020 г.
* Author: LeonidTitov
*/
#include "MoveToPoint.hh"
#include <cmath>
#include <cstring>
bool technological::function::MoveToPoint::run( const char * value,
std::size_t size ) {
if( sizeof(Input) != size )
return not(run_result = SizeError);
Input input;
std::memcpy( &input, value, size );
if( not validate(input) )
return not(run_result = InvalidInput);
if( not handle(input) )
return not(run_result = ControlSystemBusy);
return not(run_result = Empty);
}
void technological::function::MoveToPoint::stop() {
if( not control_system )
return;
moving = false;
setpoint = result.position = result.setpoint = NAN;
control_system = nullptr;
wrapper->disconnect();
torque_limit->set( stored.torque_limit );
torque_limit.unlock();
acc_limit->set( stored.acceleration_limit );
acc_limit.unlock();
speed_limit->set( stored.speed_limit );
speed_limit.unlock();
on_end();
wrapper.unlock();
}
bool technological::function::MoveToPoint::getResult( char * value,
std::size_t size ) const {
if( size != sizeof(Output) )
return false;
Output output;
output = result;
std::memcpy( value, &output, sizeof(Output) );
return true;
}
short technological::function::MoveToPoint::getState() const {
using namespace std;
if( control_system and not moving )
return ITechFunction::FINISHED;
if( control_system and moving )
return ITechFunction::EXECUTE;
if( not control_system )
return ITechFunction::DISABLE;
}
void technological::function::MoveToPoint::process() {
using namespace std;
if( moving and control_system ) {
if( fabsf( control_system->get() - setpoint ) < retention_accuracy ) {
if( not on_position_timer.isActive() )
on_position_timer.start(timeout);
} else
on_position_timer.stop();
if( on_position_timer.delayFinished() ) {
result.position = control_system->get();
result.setpoint = setpoint;
moving = false;
} else in_progress();
}
}
technological::function::MoveToPoint::MoveToPoint(
ResourceKeeper< technological::adapter::TieInterface<vector::ITechValue> > & control_system_wrapper,
ResourceKeeper<vector::ITechValue> & speed_limit,
ResourceKeeper<vector::ITechValue> & torque_limit,
ResourceKeeper<vector::ITechValue> & acc_limit ) :
wrapper(control_system_wrapper),
speed_limit(speed_limit), torque_limit(torque_limit), acc_limit(acc_limit),
setpoint(NAN), moving(false), retention_accuracy(0.0f),
stored(), run_result(Empty) {
result.position = NAN;
result.setpoint = NAN;
}
technological::function::MoveToPoint::Setting::Setting() : retention_accuracy(0.0f), on_position_timeout(0.0f) {}
bool technological::function::MoveToPoint::Setting::isValid() {
using namespace std;
const Setting not_valid;
if( retention_accuracy <= 0.0f or not isfinite(retention_accuracy) )
retention_accuracy = not_valid.retention_accuracy;
if( on_position_timeout <= 0.0f or not isfinite(retention_accuracy) )
on_position_timeout = not_valid.on_position_timeout;
return retention_accuracy != not_valid.retention_accuracy
and on_position_timeout != not_valid.on_position_timeout;
}
void technological::function::MoveToPoint::configure( Setting & config ) {
retention_accuracy = config.retention_accuracy;
timeout = systemic::seconds2time( config.on_position_timeout );
}
void technological::function::MoveToPoint::apply( Input & input ) {
acc_limit->set(input.acc_lim);
torque_limit->set(input.torque_lim);
speed_limit->set(input.speed_lim);
control_system->set(setpoint = input.position_stp);
moving = true;
on_position_timer.stop();
on_start(input, control_system->get(), timeout);
}
bool technological::function::MoveToPoint::handle( Input & input ) {
if( control_system ) {
apply(input);
} else {
ScopeLock<
Locable<vector::ITechValue>,
Locable<vector::ITechValue>,
Locable<vector::ITechValue>,
Locable< technological::adapter::TieInterface<vector::ITechValue> >
> lock( acc_limit, speed_limit, torque_limit, wrapper );
if( lock and (control_system = wrapper->try_connect()) ) {
stored.acceleration_limit = acc_limit->get();
stored.speed_limit = speed_limit->get();
stored.torque_limit = torque_limit->get();
apply(input);
lock.freeze();
}
}
return bool(control_system);
}
bool technological::function::MoveToPoint::validate( Input & input ) {
using namespace std;
if( input.acc_lim <= 0.0f or input.speed_lim <= 0.0f or input.torque_lim <= 0.0f )
return false;
if( not isfinite( input.position_stp ) )
return false;
return true;
}
bool technological::function::MoveToPoint::isSizeError() const {
return run_result == SizeError;
}
bool technological::function::MoveToPoint::isInvalidInput() const {
return run_result == InvalidInput;
}
bool technological::function::MoveToPoint::isControlSystemBusy() const {
return run_result == ControlSystemBusy;
}