/* * MoveToPoint.cpp * * Created on: 8 èþë. 2020 ã. * Author: LeonidTitov */ #include "MoveToPoint.hh" #include #include 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 > & control_system_wrapper, ResourceKeeper & speed_limit, ResourceKeeper & torque_limit, ResourceKeeper & 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, Locable, Locable, Locable< technological::adapter::TieInterface > > 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; }