@ -44,6 +44,8 @@
@@ -44,6 +44,8 @@
# include <uORB/topics/vehicle_roi.h>
# include <uORB/topics/vehicle_command_ack.h>
# include <uORB/topics/position_setpoint_triplet.h>
# include <uORB/topics/gimbal_manager_set_attitude.h>
# include <uORB/topics/gimbal_manager_set_manual_control.h>
# include <drivers/drv_hrt.h>
# include <lib/parameters/param.h>
# include <px4_platform_common/defines.h>
@ -176,17 +178,6 @@ void InputMavlinkROI::print_status()
@@ -176,17 +178,6 @@ void InputMavlinkROI::print_status()
InputMavlinkCmdMount : : InputMavlinkCmdMount ( )
{
param_t handle = param_find ( " MAV_SYS_ID " ) ;
if ( handle ! = PARAM_INVALID ) {
param_get ( handle , & _mav_sys_id ) ;
}
handle = param_find ( " MAV_COMP_ID " ) ;
if ( handle ! = PARAM_INVALID ) {
param_get ( handle , & _mav_comp_id ) ;
}
}
InputMavlinkCmdMount : : ~ InputMavlinkCmdMount ( )
@ -273,24 +264,30 @@ int InputMavlinkCmdMount::update_impl(unsigned int timeout_ms, ControlData **con
@@ -273,24 +264,30 @@ int InputMavlinkCmdMount::update_impl(unsigned int timeout_ms, ControlData **con
* control_data = & _control_data ;
break ;
case vehicle_command_s : : VEHICLE_MOUNT_MODE_MAVLINK_TARGETING :
case vehicle_command_s : : VEHICLE_MOUNT_MODE_MAVLINK_TARGETING : {
_control_data . type = ControlData : : Type : : Angle ;
_control_data . type_data . angle . frames [ 0 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 1 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 2 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
// vmount spec has roll on channel 0, MAVLink spec has pitch on channel 0
_control_data . type_data . angle . angles [ 0 ] = vehicle_command . param2 * M_DEG_TO_RAD_F ;
const float roll = vehicle_command . param2 * M_DEG_TO_RAD_F ;
// vmount spec has pitch on channel 1, MAVLink spec has roll on channel 1
_control_data . type_data . angle . angles [ 1 ] = vehicle_command . param1 * M_DEG_TO_RAD_F ;
const float pitch = vehicle_command . param1 * M_DEG_TO_RAD_F ;
// both specs have yaw on channel 2
_control_data . type_data . angle . angles [ 2 ] = vehicle_command . param3 * M_DEG_TO_RAD_F ;
float yaw = vehicle_command . param3 * M_DEG_TO_RAD_F ;
// We expect angle of [-pi..+pi]. If the input range is [0..2pi] we can fix that.
if ( _control_data . type_data . angle . angles [ 2 ] > M_PI_F ) {
_control_data . type_data . angle . angles [ 2 ] - = 2 * M_PI_F ;
}
matrix : : Eulerf euler ( roll , pitch , yaw ) ;
matrix : : Quatf q ( euler ) ;
q . copyTo ( _control_data . type_data . angle . q ) ;
_control_data . type_data . angle . angular_velocity [ 0 ] = NAN ;
_control_data . type_data . angle . angular_velocity [ 1 ] = NAN ;
_control_data . type_data . angle . angular_velocity [ 2 ] = NAN ;
* control_data = & _control_data ;
}
break ;
case vehicle_command_s : : VEHICLE_MOUNT_MODE_RC_TARGETING :
@ -374,25 +371,14 @@ void InputMavlinkCmdMount::print_status()
@@ -374,25 +371,14 @@ void InputMavlinkCmdMount::print_status()
PX4_INFO ( " Input: Mavlink (CMD_MOUNT) " ) ;
}
InputMavlinkGimbalV2 : : InputMavlinkGimbalV2 ( bool has_v2_gimbal_device )
InputMavlinkGimbalV2 : : InputMavlinkGimbalV2 ( bool has_v2_gimbal_device , uint8_t mav_sys_id , uint8_t mav_comp_id ,
float & mnt_rate_pitch , float & mnt_rate_yaw ) :
_mav_sys_id ( mav_sys_id ) ,
_mav_comp_id ( mav_comp_id ) ,
_mnt_rate_pitch ( mnt_rate_pitch ) ,
_mnt_rate_yaw ( mnt_rate_yaw )
{
param_t handle = param_find ( " MAV_SYS_ID " ) ;
if ( handle ! = PARAM_INVALID ) {
param_get ( handle , & _mav_sys_id ) ;
}
handle = param_find ( " MAV_COMP_ID " ) ;
if ( handle ! = PARAM_INVALID ) {
param_get ( handle , & _mav_comp_id ) ;
}
if ( has_v2_gimbal_device ) {
/* smart gimbal: ask GIMBAL_DEVICE_INFORMATION to it */
_request_gimbal_device_information ( ) ;
} else {
if ( ! has_v2_gimbal_device ) {
/* dumb gimbal or MAVLink v1 protocol gimbal: fake GIMBAL_DEVICE_INFORMATION */
_stream_gimbal_manager_information ( ) ;
}
@ -415,6 +401,10 @@ InputMavlinkGimbalV2::~InputMavlinkGimbalV2()
@@ -415,6 +401,10 @@ InputMavlinkGimbalV2::~InputMavlinkGimbalV2()
if ( _vehicle_command_sub > = 0 ) {
orb_unsubscribe ( _vehicle_command_sub ) ;
}
if ( _gimbal_manager_set_manual_control_sub > = 0 ) {
orb_unsubscribe ( _gimbal_manager_set_manual_control_sub ) ;
}
}
@ -447,6 +437,10 @@ int InputMavlinkGimbalV2::initialize()
@@ -447,6 +437,10 @@ int InputMavlinkGimbalV2::initialize()
return - errno ;
}
if ( ( _gimbal_manager_set_manual_control_sub = orb_subscribe ( ORB_ID ( gimbal_manager_set_manual_control ) ) ) < 0 ) {
return - errno ;
}
// rate-limit inputs to 100Hz. If we don't do this and the output is configured to mavlink mode,
// it will publish vehicle_command's as well, causing the input poll() in here to return
// immediately, which in turn will cause an output update and thus a busy loop.
@ -457,17 +451,21 @@ int InputMavlinkGimbalV2::initialize()
@@ -457,17 +451,21 @@ int InputMavlinkGimbalV2::initialize()
void InputMavlinkGimbalV2 : : _stream_gimbal_manager_status ( )
{
gimbal_device_attitude_status_s gimbal_device_attitude_status { } ;
if ( _gimbal_device_attitude_status_sub . updated ( ) ) {
_gimbal_device_attitude_status_sub . copy ( & _ gimbal_device_attitude_status) ;
_gimbal_device_attitude_status_sub . copy ( & gimbal_device_attitude_status ) ;
}
gimbal_manager_status_s gimbal_manager_status { } ;
gimbal_manager_status . timestamp = hrt_absolute_time ( ) ;
gimbal_manager_status . flags = _ gimbal_device_attitude_status. device_flags ;
gimbal_manager_status . flags = gimbal_device_attitude_status . device_flags ;
gimbal_manager_status . gimbal_device_id = 0 ;
gimbal_manager_status . primary_control_sysid = _sys_id_primary_control ;
gimbal_manager_status . primary_control_compid = _comp_id_primary_control ;
gimbal_manager_status . secondary_control_sysid = 0 ; // TODO: support secondary control
gimbal_manager_status . secondary_control_compid = 0 ; // TODO: support secondary control
_gimbal_manager_status_pub . publish ( gimbal_manager_status ) ;
}
void InputMavlinkGimbalV2 : : _stream_gimbal_manager_information ( )
@ -489,33 +487,14 @@ void InputMavlinkGimbalV2::_stream_gimbal_manager_information()
@@ -489,33 +487,14 @@ void InputMavlinkGimbalV2::_stream_gimbal_manager_information()
gimbal_device_information_s : : GIMBAL_DEVICE_CAP_FLAGS_HAS_YAW_AXIS |
gimbal_device_information_s : : GIMBAL_DEVICE_CAP_FLAGS_HAS_YAW_LOCK ;
gimbal_device_info . tilt_max = M_PI_F / 2 ;
gimbal_device_info . tilt_min = - M_PI_F / 2 ;
gimbal_device_info . tilt_rate_max = 1 ;
gimbal_device_info . pan_max = M_PI_F ;
gimbal_device_info . pan_min = - M_PI_F ;
gimbal_device_info . pan_rate_max = 1 ;
gimbal_device_info . pitch_max = M_PI_F / 2 ;
gimbal_device_info . pitch_min = - M_PI_F / 2 ;
gimbal_device_info . yaw_max = M_PI_F ;
gimbal_device_info . yaw_min = - M_PI_F ;
_gimbal_device_info_pub . publish ( gimbal_device_info ) ;
}
void InputMavlinkGimbalV2 : : _request_gimbal_device_information ( )
{
vehicle_command_s vehicle_cmd { } ;
vehicle_cmd . timestamp = hrt_absolute_time ( ) ;
vehicle_cmd . command = vehicle_command_s : : VEHICLE_CMD_REQUEST_MESSAGE ;
vehicle_cmd . param1 = vehicle_command_s : : VEHICLE_CMD_GIMBAL_DEVICE_INFORMATION ;
vehicle_cmd . target_system = 0 ;
vehicle_cmd . target_component = 0 ;
vehicle_cmd . source_system = _mav_sys_id ;
vehicle_cmd . source_component = _mav_comp_id ;
vehicle_cmd . confirmation = 0 ;
vehicle_cmd . from_external = false ;
uORB : : PublicationQueued < vehicle_command_s > vehicle_command_pub { ORB_ID ( vehicle_command ) } ;
vehicle_command_pub . publish ( vehicle_cmd ) ;
}
int InputMavlinkGimbalV2 : : update_impl ( unsigned int timeout_ms , ControlData * * control_data , bool already_active )
{
_stream_gimbal_manager_status ( ) ;
@ -523,7 +502,7 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
@@ -523,7 +502,7 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
// Default to no change, set if we receive anything.
* control_data = nullptr ;
const int num_poll = 4 ;
const int num_poll = 5 ;
px4_pollfd_struct_t polls [ num_poll ] ;
polls [ 0 ] . fd = _gimbal_manager_set_attitude_sub ;
polls [ 0 ] . events = POLLIN ;
@ -533,6 +512,8 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
@@ -533,6 +512,8 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
polls [ 2 ] . events = POLLIN ;
polls [ 3 ] . fd = _vehicle_command_sub ;
polls [ 3 ] . events = POLLIN ;
polls [ 4 ] . fd = _gimbal_manager_set_manual_control_sub ;
polls [ 4 ] . events = POLLIN ;
int poll_timeout = ( int ) timeout_ms ;
@ -560,13 +541,20 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
@@ -560,13 +541,20 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
gimbal_manager_set_attitude_s set_attitude ;
orb_copy ( ORB_ID ( gimbal_manager_set_attitude ) , _gimbal_manager_set_attitude_sub , & set_attitude ) ;
const float pitch = matrix : : Eulerf ( matrix : : Quatf ( set_attitude . q ) ) . phi ( ) ; // rad
const float roll = matrix : : Eulerf ( matrix : : Quatf ( set_attitude . q ) ) . theta ( ) ;
const float yaw = matrix : : Eulerf ( matrix : : Quatf ( set_attitude . q ) ) . psi ( ) ;
if ( set_attitude . origin_sysid = = _sys_id_primary_control & &
set_attitude . origin_compid = = _comp_id_primary_control ) {
const matrix : : Quatf q ( set_attitude . q ) ;
const matrix : : Vector3f angular_velocity ( set_attitude . angular_velocity_x ,
set_attitude . angular_velocity_y ,
set_attitude . angular_velocity_z ) ;
_set_control_data_from_set_attitude ( set_attitude . flags , pitch , set_attitude . angular_velocity_y , yaw ,
set_attitude . angular_velocity_z , roll , set_attitude . angular_velocity_x ) ;
_set_control_data_from_set_attitude ( set_attitude . flags , q , angular_velocity ) ;
* control_data = & _control_data ;
} else {
PX4_WARN ( " Ignoring gimbal_manager_set_attitude from %d/%d " ,
set_attitude . origin_sysid , set_attitude . origin_compid ) ;
}
}
if ( polls [ 1 ] . revents & POLLIN ) {
@ -642,16 +630,233 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
@@ -642,16 +630,233 @@ int InputMavlinkGimbalV2::update_impl(unsigned int timeout_ms, ControlData **con
continue ;
}
if ( vehicle_command . command = = vehicle_command_s : : VEHICLE_CMD_DO_GIMBAL_MANAGER_ATTITUDE ) {
_set_control_data_from_set_attitude ( ( uint32_t ) vehicle_command . param5 , vehicle_command . param3 , vehicle_command . param1 ,
vehicle_command . param3 , vehicle_command . param2 ) ;
if ( vehicle_command . command = = vehicle_command_s : : VEHICLE_CMD_DO_MOUNT_CONTROL ) {
// FIXME: Remove me later. For now, we support this for legacy missions
// using gimbal v1 protocol.
switch ( ( int ) vehicle_command . param7 ) {
case vehicle_command_s : : VEHICLE_MOUNT_MODE_RETRACT :
_control_data . gimbal_shutter_retract = true ;
/* FALLTHROUGH */
case vehicle_command_s : : VEHICLE_MOUNT_MODE_NEUTRAL :
_control_data . type = ControlData : : Type : : Neutral ;
* control_data = & _control_data ;
_ack_vehicle_command ( & vehicle_command ) ;
break ;
case vehicle_command_s : : VEHICLE_MOUNT_MODE_MAVLINK_TARGETING : {
_control_data . type = ControlData : : Type : : Angle ;
_control_data . type_data . angle . frames [ 0 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 1 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 2 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
// vmount spec has roll on channel 0, MAVLink spec has pitch on channel 0
const float roll = vehicle_command . param2 * M_DEG_TO_RAD_F ;
// vmount spec has pitch on channel 1, MAVLink spec has roll on channel 1
const float pitch = vehicle_command . param1 * M_DEG_TO_RAD_F ;
// both specs have yaw on channel 2
float yaw = vehicle_command . param3 * M_DEG_TO_RAD_F ;
// We expect angle of [-pi..+pi]. If the input range is [0..2pi] we can fix that.
if ( yaw > M_PI_F ) {
yaw - = 2 * M_PI_F ;
}
matrix : : Eulerf euler ( roll , pitch , yaw ) ;
matrix : : Quatf q ( euler ) ;
q . copyTo ( _control_data . type_data . angle . q ) ;
_control_data . type_data . angle . angular_velocity [ 0 ] = NAN ;
_control_data . type_data . angle . angular_velocity [ 1 ] = NAN ;
_control_data . type_data . angle . angular_velocity [ 2 ] = NAN ;
* control_data = & _control_data ;
}
break ;
case vehicle_command_s : : VEHICLE_MOUNT_MODE_RC_TARGETING :
break ;
case vehicle_command_s : : VEHICLE_MOUNT_MODE_GPS_POINT :
control_data_set_lon_lat ( ( double ) vehicle_command . param6 , ( double ) vehicle_command . param5 , vehicle_command . param4 ) ;
* control_data = & _control_data ;
break ;
}
_ack_vehicle_command ( & vehicle_command , vehicle_command_s : : VEHICLE_CMD_RESULT_ACCEPTED ) ;
} else if ( vehicle_command . command = = vehicle_command_s : : VEHICLE_CMD_DO_MOUNT_CONFIGURE ) {
_control_data . stabilize_axis [ 0 ] = ( int ) ( vehicle_command . param2 + 0.5f ) = = 1 ;
_control_data . stabilize_axis [ 1 ] = ( int ) ( vehicle_command . param3 + 0.5f ) = = 1 ;
_control_data . stabilize_axis [ 2 ] = ( int ) ( vehicle_command . param4 + 0.5f ) = = 1 ;
const int params [ ] = {
( int ) ( ( float ) vehicle_command . param5 + 0.5f ) ,
( int ) ( ( float ) vehicle_command . param6 + 0.5f ) ,
( int ) ( vehicle_command . param7 + 0.5f )
} ;
for ( int i = 0 ; i < 3 ; + + i ) {
if ( params [ i ] = = 0 ) {
_control_data . type_data . angle . frames [ i ] =
ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
} else if ( params [ i ] = = 1 ) {
_control_data . type_data . angle . frames [ i ] =
ControlData : : TypeData : : TypeAngle : : Frame : : AngularRate ;
} else if ( params [ i ] = = 2 ) {
_control_data . type_data . angle . frames [ i ] =
ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame ;
} else {
// Not supported, fallback to body angle.
_control_data . type_data . angle . frames [ i ] =
ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
}
}
_control_data . type = ControlData : : Type : : Neutral ; //always switch to neutral position
* control_data = & _control_data ;
_ack_vehicle_command ( & vehicle_command , vehicle_command_s : : VEHICLE_CMD_RESULT_ACCEPTED ) ;
} else if ( vehicle_command . command = = vehicle_command_s : : VEHICLE_CMD_DO_GIMBAL_MANAGER_CONFIGURE ) {
const int param_sys_id = roundf ( vehicle_command . param1 ) ;
const int param_comp_id = roundf ( vehicle_command . param2 ) ;
uint8_t new_sys_id_primary_control = [ & ] ( ) {
if ( param_sys_id > = 0 & & param_sys_id < 256 ) {
// Valid new sysid.
return ( uint8_t ) param_sys_id ;
} else if ( param_sys_id = = - 1 ) {
// leave unchanged
return _sys_id_primary_control ;
} else if ( param_sys_id = = - 2 ) {
// set itself
return _mav_sys_id ;
} else if ( param_sys_id = = - 3 ) {
// release control if in control
if ( _sys_id_primary_control = = vehicle_command . source_system ) {
return ( uint8_t ) 0 ;
} else {
return _sys_id_primary_control ;
}
} else {
PX4_WARN ( " Unknown param1 value for DO_GIMBAL_MANAGER_CONFIGURE " ) ;
return _sys_id_primary_control ;
}
} ( ) ;
uint8_t new_comp_id_primary_control = [ & ] ( ) {
if ( param_comp_id > = 0 & & param_comp_id < 256 ) {
// Valid new compid.
return ( uint8_t ) param_comp_id ;
} else if ( param_comp_id = = - 1 ) {
// leave unchanged
return _comp_id_primary_control ;
} else if ( param_comp_id = = - 2 ) {
// set itself
return _mav_comp_id ;
} else if ( param_comp_id = = - 3 ) {
// release control if in control
if ( _comp_id_primary_control = = vehicle_command . source_component ) {
return ( uint8_t ) 0 ;
} else {
return _comp_id_primary_control ;
}
} else {
PX4_WARN ( " Unknown param2 value for DO_GIMBAL_MANAGER_CONFIGURE " ) ;
return _comp_id_primary_control ;
}
} ( ) ;
if ( new_sys_id_primary_control ! = _sys_id_primary_control | |
new_comp_id_primary_control ! = _comp_id_primary_control ) {
PX4_INFO ( " Configured primary gimbal control sysid/compid from %d/%d to %d/%d " ,
_sys_id_primary_control , _comp_id_primary_control ,
new_sys_id_primary_control , new_comp_id_primary_control ) ;
_sys_id_primary_control = new_sys_id_primary_control ;
_comp_id_primary_control = new_comp_id_primary_control ;
}
// TODO: support secondary control
// TODO: support gimbal device id for multiple gimbals
_ack_vehicle_command ( & vehicle_command , vehicle_command_s : : VEHICLE_CMD_RESULT_ACCEPTED ) ;
} else if ( vehicle_command . command = = vehicle_command_s : : VEHICLE_CMD_DO_GIMBAL_MANAGER_PITCHYAW ) {
if ( vehicle_command . source_system = = _sys_id_primary_control & &
vehicle_command . source_component = = _comp_id_primary_control ) {
const matrix : : Eulerf euler ( 0.0f , vehicle_command . param1 * M_DEG_TO_RAD_F , vehicle_command . param2 * M_DEG_TO_RAD_F ) ;
const matrix : : Quatf q ( euler ) ;
const matrix : : Vector3f angular_velocity ( 0.0f , vehicle_command . param3 , vehicle_command . param4 ) ;
const uint32_t flags = vehicle_command . param5 ;
// TODO: support gimbal device id for multiple gimbals
_set_control_data_from_set_attitude ( flags , q , angular_velocity ) ;
* control_data = & _control_data ;
_ack_vehicle_command ( & vehicle_command , vehicle_command_s : : VEHICLE_CMD_RESULT_ACCEPTED ) ;
} else {
PX4_ERR ( " GIMBAL_MANAGER_PITCHYAW denied, not in control " ) ;
_ack_vehicle_command ( & vehicle_command , vehicle_command_s : : VEHICLE_CMD_RESULT_DENIED ) ;
}
} else {
exit_loop = false ;
}
}
if ( polls [ 4 ] . revents & POLLIN ) {
gimbal_manager_set_manual_control_s set_manual_control ;
orb_copy ( ORB_ID ( gimbal_manager_set_manual_control ) , _gimbal_manager_set_manual_control_sub , & set_manual_control ) ;
if ( set_manual_control . origin_sysid = = _sys_id_primary_control & &
set_manual_control . origin_compid = = _comp_id_primary_control ) {
const matrix : : Quatf q =
( PX4_ISFINITE ( set_manual_control . pitch ) & & PX4_ISFINITE ( set_manual_control . yaw ) ) ?
matrix : : Quatf ( matrix : : Eulerf ( 0.0f , set_manual_control . pitch , set_manual_control . yaw ) ) :
matrix : : Quatf ( NAN , NAN , NAN , NAN ) ;
const matrix : : Vector3f angular_velocity =
( PX4_ISFINITE ( set_manual_control . pitch_rate ) & & PX4_ISFINITE ( set_manual_control . yaw_rate ) ) ?
matrix : : Vector3f ( 0.0f ,
_mnt_rate_pitch * M_DEG_TO_RAD_F * set_manual_control . pitch_rate ,
_mnt_rate_yaw * M_DEG_TO_RAD_F * set_manual_control . yaw_rate ) :
matrix : : Vector3f ( NAN , NAN , NAN ) ;
_set_control_data_from_set_attitude ( set_manual_control . flags , q , angular_velocity ) ;
* control_data = & _control_data ;
} else {
PX4_WARN ( " Ignoring gimbal_manager_set_manual_control from %d/%d " ,
set_manual_control . origin_sysid , set_manual_control . origin_compid ) ;
}
}
}
}
@ -671,25 +876,30 @@ void InputMavlinkGimbalV2::_transform_lon_lat_to_angle(const double roi_lon, con
@@ -671,25 +876,30 @@ void InputMavlinkGimbalV2::_transform_lon_lat_to_angle(const double roi_lon, con
_control_data . type_data . angle . frames [ 1 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 2 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . angles [ 0 ] = 0.f ;
const float roll = 0.0f ;
float pitch = 0.0f ;
float yaw = 0.0f ;
// interface: use fixed pitch value > -pi otherwise consider ROI altitude
if ( _control_data . type_data . lonlat . pitch_fixed_angle > = - M_PI_F ) {
_control_data . type_data . angle . angles [ 1 ] = _control_data . type_data . lonlat . pitch_fixed_angle ;
pitch = _control_data . type_data . lonlat . pitch_fixed_angle ;
} else {
_control_data . type_data . angle . angles [ 1 ] = _calculate_pitch ( roi_lon , roi_lat , roi_alt , vehicle_global_position ) ;
pitch = _calculate_pitch ( roi_lon , roi_lat , roi_alt , vehicle_global_position ) ;
}
_control_data . type_data . angle . angles [ 2 ] = get_bearing_to_next_waypoint ( vlat , vlon , roi_lat ,
roi_lon ) - vehicle_global_position . yaw ;
yaw = get_bearing_to_next_waypoint ( vlat , vlon , roi_lat , roi_lon ) - vehicle_local_position . yaw ;
// add offsets from VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET
_control_data . type_data . angle . angles [ 1 ] + = _control_data . type_data . lonlat . pitch_angle_offset ;
_control_data . type_data . angle . angles [ 2 ] + = _control_data . type_data . lonlat . yaw_angle_offset ;
pitch + = _control_data . type_data . lonlat . pitch_angle_offset ;
yaw + = _control_data . type_data . lonlat . yaw_angle_offset ;
// make sure yaw is wrapped correctly for the output
_control_data . type_data . angle . angles [ 2 ] = wrap_pi ( _control_data . type_data . angle . angles [ 2 ] ) ;
yaw = wrap_pi ( yaw ) ;
matrix : : Eulerf euler ( roll , pitch , yaw ) ;
matrix : : Quatf q ( euler ) ;
q . copyTo ( _control_data . type_data . angle . q ) ;
}
float InputMavlinkGimbalV2 : : _calculate_pitch ( double lon , double lat , float altitude ,
@ -718,81 +928,48 @@ void InputMavlinkGimbalV2::_read_lat_lon_alt_from_position_setpoint_sub(double &
@@ -718,81 +928,48 @@ void InputMavlinkGimbalV2::_read_lat_lon_alt_from_position_setpoint_sub(double &
alt_sp = ( double ) position_setpoint_triplet . current . alt ;
}
void InputMavlinkGimbalV2 : : _set_control_data_from_set_attitude ( const uint32_t flags , const float pitch_angle ,
const float pitch_rate , const float yaw_angle , const float yaw_rate , float roll_angle , float roll_rate )
void InputMavlinkGimbalV2 : : _set_control_data_from_set_attitude ( const uint32_t flags , const matrix : : Quatf & q ,
const matrix : : Vector3f & angular_velocity )
{
if ( ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_RETRACT ) ! = 0 ) {
// not implemented in ControlData
} else if ( ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_NEUTRAL ) ! = 0 ) {
_control_data . type = ControlData : : Type : : Neutral ;
} else if ( ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_NONE ) ! = 0 ) {
// don't do anything
} else {
_control_data . type = ControlData : : Type : : Angle ;
_control_data . type_data . angle . frames [ 0 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 1 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
_control_data . type_data . angle . frames [ 2 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
if ( _is_roi_set & & ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_NUDGE ) ! = 0 ) {
// add set_attitude.q to existing tracking angle or ROI
// track message not yet implemented
_control_data . type_data . angle . angles [ 0 ] + = pitch_angle ;
_control_data . type_data . angle . angles [ 1 ] + = roll_angle ;
_control_data . type_data . angle . angles [ 2 ] + = yaw_angle ;
} else {
_control_data . type_data . angle . angles [ 0 ] = pitch_angle ;
_control_data . type_data . angle . angles [ 1 ] = roll_angle ;
_control_data . type_data . angle . angles [ 2 ] = yaw_angle ;
}
if ( _is_roi_set & & ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_OVERRIDE ) ! = 0 ) {
// overides tracking or ROI angle with set_attitude.q, respects flag GIMBAL_MANAGER_FLAGS_YAW_LOCK
_control_data . type_data . angle . angles [ 0 ] = pitch_angle ;
_control_data . type_data . angle . angles [ 1 ] = roll_angle ;
_control_data . type_data . angle . angles [ 2 ] = yaw_angle ;
}
_control_data . type_data . angle . q [ 0 ] = q ( 0 ) ;
_control_data . type_data . angle . q [ 1 ] = q ( 1 ) ;
_control_data . type_data . angle . q [ 2 ] = q ( 2 ) ;
_control_data . type_data . angle . q [ 3 ] = q ( 3 ) ;
if ( PX4_ISFINITE ( roll_rate ) ) { //roll
_control_data . type_data . angle . frames [ 0 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngularRate ;
_control_data . type_data . angle . angles [ 0 ] = roll_rate ; //rad/s
}
_control_data . type_data . angle . angular_velocity [ 0 ] = angular_velocity ( 0 ) ;
_control_data . type_data . angle . angular_velocity [ 1 ] = angular_velocity ( 1 ) ;
_control_data . type_data . angle . angular_velocity [ 2 ] = angular_velocity ( 2 ) ;
if ( PX4_ISFINITE ( pitch_rate ) ) { //pitch
_control_data . type_data . angle . frames [ 1 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngularRate ;
_control_data . type_data . angle . angles [ 1 ] = pitch_rate ; //rad/s
}
_control_data . type_data . angle . frames [ 0 ] = ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_ROLL_LOCK )
? ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame
: ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
if ( PX4_ISFINITE ( yaw_rate ) ) { //yaw
_control_data . type_data . angle . frames [ 2 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngularRate ;
_control_data . type_data . angle . angles [ 2 ] = yaw_rate ; //rad/s
}
_control_data . type_data . angle . frames [ 1 ] = ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_PITCH_LOCK )
? ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame
: ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
if ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_ROLL_LOCK ) {
// stay horizontal with the horizon
_control_data . type_data . angle . frames [ 0 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame ;
}
if ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_PITCH_LOCK ) {
_control_data . type_data . angle . frames [ 1 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame ;
}
if ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_YAW_LOCK ) {
_control_data . type_data . angle . frames [ 2 ] = ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame ;
}
_control_data . type_data . angle . frames [ 2 ] = ( flags & gimbal_manager_set_attitude_s : : GIMBAL_MANAGER_FLAGS_YAW_LOCK )
? ControlData : : TypeData : : TypeAngle : : Frame : : AngleAbsoluteFrame
: ControlData : : TypeData : : TypeAngle : : Frame : : AngleBodyFrame ;
}
}
//TODO move this one to input.cpp such that it can be shared across functions
void InputMavlinkGimbalV2 : : _ack_vehicle_command ( vehicle_command_s * cmd )
void InputMavlinkGimbalV2 : : _ack_vehicle_command ( vehicle_command_s * cmd , uint8_t result )
{
vehicle_command_ack_s vehicle_command_ack { } ;
vehicle_command_ack . timestamp = hrt_absolute_time ( ) ;
vehicle_command_ack . command = cmd - > command ;
vehicle_command_ack . result = vehicle_command_s : : VEHICLE_CMD_RESULT_ACCEPTED ;
vehicle_command_ack . result = result ;
vehicle_command_ack . target_system = cmd - > source_system ;
vehicle_command_ack . target_component = cmd - > source_component ;