@ -77,6 +77,8 @@ VtolType::VtolType(VtolAttitudeControl *att_controller) :
@@ -77,6 +77,8 @@ VtolType::VtolType(VtolAttitudeControl *att_controller) :
for ( auto & pwm_disarmed : _disarmed_pwm_values . values ) {
pwm_disarmed = PWM_MOTOR_OFF ;
}
_current_max_pwm_values = _max_mc_pwm_values ;
}
bool VtolType : : init ( )
@ -117,6 +119,17 @@ bool VtolType::init()
@@ -117,6 +119,17 @@ bool VtolType::init()
px4_close ( fd ) ;
_main_motor_channel_bitmap = generate_bitmap_from_channel_numbers ( _params - > vtol_motor_id ) ;
_alternate_motor_channel_bitmap = generate_bitmap_from_channel_numbers ( _params - > fw_motors_off ) ;
// in order to get the main motors we take all motors and clear the alternate motor bits
for ( int i = 0 ; i < 8 ; i + + ) {
if ( _alternate_motor_channel_bitmap & ( 1 < < i ) ) {
_main_motor_channel_bitmap & = ~ ( 1 < < i ) ;
}
}
return true ;
}
@ -127,9 +140,7 @@ void VtolType::update_mc_state()
@@ -127,9 +140,7 @@ void VtolType::update_mc_state()
_flag_idle_mc = set_idle_mc ( ) ;
}
if ( _motor_state ! = motor_state : : ENABLED ) {
_motor_state = VtolType : : set_motor_state ( _motor_state , motor_state : : ENABLED ) ;
}
VtolType : : set_all_motor_state ( motor_state : : ENABLED ) ;
// copy virtual attitude setpoint to real attitude setpoint
memcpy ( _v_att_sp , _mc_virtual_att_sp , sizeof ( vehicle_attitude_setpoint_s ) ) ;
@ -146,9 +157,7 @@ void VtolType::update_fw_state()
@@ -146,9 +157,7 @@ void VtolType::update_fw_state()
_flag_idle_mc = ! set_idle_fw ( ) ;
}
if ( _motor_state ! = motor_state : : DISABLED ) {
_motor_state = VtolType : : set_motor_state ( _motor_state , motor_state : : DISABLED ) ;
}
VtolType : : set_alternate_motor_state ( motor_state : : DISABLED ) ;
// copy virtual attitude setpoint to real attitude setpoint
memcpy ( _v_att_sp , _fw_virtual_att_sp , sizeof ( vehicle_attitude_setpoint_s ) ) ;
@ -291,7 +300,7 @@ bool VtolType::set_idle_mc()
@@ -291,7 +300,7 @@ bool VtolType::set_idle_mc()
struct pwm_output_values pwm_values { } ;
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
if ( is_channel_set ( i , _params - > vtol_motor_id ) ) {
if ( is_channel_set ( i , generate_bitmap_from_channel_numbers ( _params - > vtol_motor_id ) ) ) {
pwm_values . values [ i ] = pwm_value ;
} else {
@ -309,7 +318,7 @@ bool VtolType::set_idle_fw()
@@ -309,7 +318,7 @@ bool VtolType::set_idle_fw()
struct pwm_output_values pwm_values { } ;
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
if ( is_channel_set ( i , _params - > vtol_motor_id ) ) {
if ( is_channel_set ( i , generate_bitmap_from_channel_numbers ( _params - > vtol_motor_id ) ) ) {
pwm_values . values [ i ] = PWM_MOTOR_OFF ;
} else {
@ -353,24 +362,48 @@ bool VtolType::apply_pwm_limits(struct pwm_output_values &pwm_values, pwm_limit_
@@ -353,24 +362,48 @@ bool VtolType::apply_pwm_limits(struct pwm_output_values &pwm_values, pwm_limit_
return true ;
}
motor_state VtolType : : set_motor_state ( const motor_state current_state , const motor_state nex t_state, const int value )
void VtolType : : set_all_ motor_state ( const motor_state targe t_state, const int value )
{
struct pwm_output_values pwm_values = { } ;
pwm_values . channel_count = num_outputs_max ;
set_main_motor_state ( target_state , value ) ;
set_alternate_motor_state ( target_state , value ) ;
}
// per default all motors are running
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
pwm_values . values [ i ] = _max_mc_pwm_values . values [ i ] ;
void VtolType : : set_main_motor_state ( const motor_state target_state , const int value )
{
if ( _main_motor_state ! = target_state ) {
if ( set_motor_state ( target_state , _main_motor_channel_bitmap , value ) ) {
_main_motor_state = target_state ;
}
}
}
void VtolType : : set_alternate_motor_state ( const motor_state target_state , const int value )
{
if ( _alternate_motor_state ! = target_state ) {
switch ( next_state ) {
if ( set_motor_state ( target_state , _alternate_motor_channel_bitmap , value ) ) {
_alternate_motor_state = target_state ;
}
}
}
bool VtolType : : set_motor_state ( const motor_state target_state , const int32_t channel_bitmap , const int value )
{
switch ( target_state ) {
case motor_state : : ENABLED :
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
if ( is_channel_set ( i , channel_bitmap ) ) {
_current_max_pwm_values . values [ i ] = _max_mc_pwm_values . values [ i ] ;
}
}
break ;
case motor_state : : DISABLED :
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
if ( is_channel_set ( i , _params - > fw_motors_off ) ) {
pwm_values . values [ i ] = _disarmed_pwm_values . values [ i ] ;
if ( is_channel_set ( i , channel_bitmap ) ) {
_current_max_ pwm_values. values [ i ] = _disarmed_pwm_values . values [ i ] ;
}
}
@ -379,8 +412,8 @@ motor_state VtolType::set_motor_state(const motor_state current_state, const mot
@@ -379,8 +412,8 @@ motor_state VtolType::set_motor_state(const motor_state current_state, const mot
case motor_state : : IDLE :
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
if ( is_channel_set ( i , _params - > vtol_motor_id ) ) {
pwm_values . values [ i ] = _params - > idle_pwm_mc ;
if ( is_channel_set ( i , channel_bitmap ) ) {
_current_max_ pwm_values. values [ i ] = _params - > idle_pwm_mc ;
}
}
@ -388,42 +421,43 @@ motor_state VtolType::set_motor_state(const motor_state current_state, const mot
@@ -388,42 +421,43 @@ motor_state VtolType::set_motor_state(const motor_state current_state, const mot
case motor_state : : VALUE :
for ( int i = 0 ; i < num_outputs_max ; i + + ) {
if ( is_channel_set ( i , _params - > fw_motors_off ) ) {
pwm_values . values [ i ] = value ;
if ( is_channel_set ( i , channel_bitmap ) ) {
_current_max_ pwm_values. values [ i ] = value ;
}
}
break ;
}
if ( apply_pwm_limits ( pwm_values , pwm_limit_type : : TYPE_MAXIMUM ) ) {
return next_state ;
_current_max_pwm_values . channel_count = num_outputs_max ;
} else {
return current_state ;
}
return apply_pwm_limits ( _current_max_pwm_values , pwm_limit_type : : TYPE_MAXIMUM ) ;
}
bool VtolType : : is_channel_set ( const int channel , const int target )
int VtolType : : generate_bitmap_from_channel_numbers ( const int channels )
{
int channel_bitmap = 0 ;
int channel_numbers = channels ;
int tmp ;
int channels = target ;
for ( int i = 0 ; i < num_outputs_max ; + + i ) {
tmp = channels % 10 ;
tmp = channel_number s % 10 ;
if ( tmp = = 0 ) {
break ;
}
channel_bitmap | = 1 < < ( tmp - 1 ) ;
channels = channels / 10 ;
channel_number s = channel_number s / 10 ;
}
return ( channel_bitmap > > channel ) & 1 ;
return channel_bitmap ;
}
bool VtolType : : is_channel_set ( const int channel , const int bitmap )
{
return bitmap & ( 1 < < channel ) ;
}