Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion boards/auterion/fmu-v6x/default.px4board
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y
CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_SENSORS=y
CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y
CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=n
CONFIG_MODULES_UXRCE_DDS_CLIENT=y
CONFIG_MODULES_VTOL_ATT_CONTROL=y
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
Expand Down
3 changes: 3 additions & 0 deletions boards/auterion/fmu-v6x/zenoh.px4board
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ CONFIG_MODULES_UXRCE_DDS_CLIENT=n
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=n
CONFIG_SYSTEMCMDS_SD_BENCH=n
CONFIG_SYSTEMCMDS_I2CDETECT=n
CONFIG_MODULES_GIMBAL=n
CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=n
CONFIG_MODULES_ROVER_MECANUM=n
CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n
CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=n
CONFIG_MODULES_ZENOH=y
3 changes: 3 additions & 0 deletions msg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ set(msg_files
EstimatorStates.msg
EstimatorStatus.msg
EstimatorStatusFlags.msg
ExternalGimbalManagerInformation.msg
ExternalGimbalManagerSetAttitude.msg
ExternalGimbalManagerStatus.msg
versioned/Event.msg
FigureEightStatus.msg
FailsafeFlags.msg
Expand Down
33 changes: 33 additions & 0 deletions msg/ExternalGimbalManagerInformation.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#Bridge-private information received from external gimbal manager
uint64 timestamp # time since system start (microseconds)

uint8 source_system
uint8 source_component

uint32 cap_flags

uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_RETRACT = 1
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_NEUTRAL = 2
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_ROLL_AXIS = 4
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_ROLL_FOLLOW = 8
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_ROLL_LOCK = 16
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_PITCH_AXIS = 32
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_PITCH_FOLLOW = 64
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_PITCH_LOCK = 128
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_AXIS = 256
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_FOLLOW = 512
uint32 GIMBAL_MANAGER_CAP_FLAGS_HAS_YAW_LOCK = 1024
uint32 GIMBAL_MANAGER_CAP_FLAGS_SUPPORTS_INFINITE_YAW = 2048
uint32 GIMBAL_MANAGER_CAP_FLAGS_CAN_POINT_LOCATION_LOCAL = 65536
uint32 GIMBAL_MANAGER_CAP_FLAGS_CAN_POINT_LOCATION_GLOBAL = 131072

uint8 gimbal_device_id

float32 roll_min # [rad]
float32 roll_max # [rad]

float32 pitch_min # [rad]
float32 pitch_max # [rad]

float32 yaw_min # [rad]
float32 yaw_max # [rad]
30 changes: 30 additions & 0 deletions msg/ExternalGimbalManagerSetAttitude.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#Bridge private set-attitude command for an external gimbal manager
uint64 timestamp # time since system start (microseconds)

uint8 origin_sysid
uint8 origin_compid

uint8 target_system
uint8 target_component

uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_RETRACT = 1
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_NEUTRAL = 2
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_ROLL_LOCK = 4
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_PITCH_LOCK = 8
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_YAW_LOCK = 16
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_YAW_IN_VEHICLE_FRAME = 32
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_YAW_IN_EARTH_FRAME = 64
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_ACCEPTS_YAW_IN_EARTH_FRAME = 128
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_RC_EXCLUSIVE = 256
uint32 EXTERNAL_GIMBAL_MANAGER_FLAGS_RC_MIXED = 512

uint32 flags
uint8 gimbal_device_id

float32[4] q

float32 angular_velocity_x
float32 angular_velocity_y
float32 angular_velocity_z

uint8 ORB_QUEUE_LENGTH = 2
14 changes: 14 additions & 0 deletions msg/ExternalGimbalManagerStatus.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#Bridge-private status received from an external gimbal manager
uint64 timestamp # time since system start (microseconds)

uint32 flags
uint8 gimbal_device_id

uint8 primary_control_sysid
uint8 primary_control_compid

uint8 secondary_control_sysid
uint8 secondary_control_compid

uint8 source_system
uint8 source_component
3 changes: 3 additions & 0 deletions msg/GimbalDeviceSetAttitude.msg
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ uint32 GIMBAL_DEVICE_FLAGS_PITCH_LOCK = 8
uint32 GIMBAL_DEVICE_FLAGS_YAW_LOCK = 16
uint32 GIMBAL_DEVICE_FLAGS_YAW_IN_VEHICLE_FRAME = 32
uint32 GIMBAL_DEVICE_FLAGS_YAW_IN_EARTH_FRAME = 64
uint32 GIMBAL_DEVICE_FLAGS_ACCEPTS_YAW_IN_EARTH_FRAME = 128
uint32 GIMBAL_DEVICE_FLAGS_RC_EXCLUSIVE = 256
uint32 GIMBAL_DEVICE_FLAGS_RC_MIXED = 512

float32[4] q

Expand Down
2 changes: 2 additions & 0 deletions msg/versioned/VehicleCommand.msg
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ uint16 VEHICLE_CMD_PREFLIGHT_STORAGE = 245 # Request storage of different parame
uint16 VEHICLE_CMD_PREFLIGHT_REBOOT_SHUTDOWN = 246 # Request the reboot or shutdown of system components. |0: Do nothing for autopilot, 1: Reboot autopilot, 2: Shutdown autopilot.|0: Do nothing for onboard computer, 1: Reboot onboard computer, 2: Shutdown onboard computer.|Unused|Unused|Unused|Unused|Unused|
uint16 VEHICLE_CMD_OBLIQUE_SURVEY=260 # Mission command to set a Camera Auto Mount Pivoting Oblique Survey for this flight. |[m] Camera trigger distance|[ms] Shutter integration time|Camera minimum trigger interval|Number of positions|Roll|Pitch|Unused|
uint16 VEHICLE_CMD_DO_SET_STANDARD_MODE=262 # Enable the specified standard MAVLink mode. |MAV_STANDARD_MODE|
uint16 VEHICLE_CMD_GIMBAL_MANAGER_INFORMATION = 280 # Command to ask information about a gimbal manager.
uint16 VEHICLE_CMD_GIMBAL_MANAGER_STATUS = 281 # Command to ask status about a gimbal manager
uint16 VEHICLE_CMD_GIMBAL_DEVICE_INFORMATION = 283 # Command to ask information about a low level gimbal.

uint16 VEHICLE_CMD_MISSION_START = 300 # Start running a mission. |first_item: the first mission item to run|last_item: the last mission item to run (after this item is run, the mission ends)|
Expand Down
33 changes: 30 additions & 3 deletions src/modules/gimbal/gimbal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
* - PWM
* - MAVLink gimbal protocol v1
* - MAVLink gimbal protocol v2
* - MAVLink gimbal protocol v2 (gimbal manager mount)
*/

#include <cstdint>
Expand Down Expand Up @@ -82,7 +83,6 @@ struct ThreadData {
};
static ThreadData *g_thread_data = nullptr;


static void usage();
static void update_params(ParameterHandles &param_handles, Parameters &params);
static bool initialize_params(ParameterHandles &param_handles, Parameters &params);
Expand All @@ -102,6 +102,21 @@ static int gimbal_thread_main(int argc, char *argv[])
return -1;
}

// When MNT_MODE_OUT = MNT_MODE_OUT_TO_GIMBAL_MANAGER,
// MNT_MODE_IN = MAVLINK_ROI || MAVLINK_DO_MOUNT || MAVLINK_V2 are NOT ALLOWED
// However, people can access MAVLINK_V2 through MNT_MODE_IN = AUTO.
const bool px4_acts_as_gimbal_manager = (params.mnt_mode_in == MNT_MODE_IN_MAVLINK_ROI)
|| (params.mnt_mode_in == MNT_MODE_IN_MAVLINK_DO_MOUNT)
|| (params.mnt_mode_in == MNT_MODE_IN_MAVLINK_V2);

const bool connected_to_external_gimbal_manager = (params.mnt_mode_out == gimbal::MNT_MODE_OUT_TO_GIMBAL_MANAGER);

// Conflict occurs when PX4 itself acts as a gimbal manager while also communicating with an external gimbal manager.
if (px4_acts_as_gimbal_manager && connected_to_external_gimbal_manager) {
PX4_ERR("MNT_MODE_OUT=MNT_MODE_OUT_TO_GIMBAL_MANAGER is only compatible with MNT_MODE_IN=AUTO or RC.");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. In theory, it should be possible to have two gimbal managers in a system: e.g. PX4 is a gimbal manager talking to its gimbal device while there is a second gimbal manager such as the integrated camera/gimbal.

Everything should then flow seamlessly through mavlink, so any gimbal command should just be sent or forwarded to the gimbal manager. I need to think more about that case.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @julianoes , that works in theory. But, PX4 default find a gimbal device with COMP_ID=MNT_MAV_COMPID which is default as 154, similar to most mavlink gimbal device. It might make the gimbal device confuse, so I made this to prevent this situation.

Also, PX4 always broadcast it as a gimbal manager even if it does not find any its gimbal device. I think this behavior is not correct.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, PX4 always broadcast it as a gimbal manager even if it does not find any its gimbal device. I think this behavior is not correct.

Indeed, so that might be the first thing to fix.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @julianoes , I tried to fix the issue PX4 always act as a gimbal manager even when a gimbal device is not belong to it.

After deep dive to the code https://github.dev/PX4/PX4-Autopilot/blob/d5f5c503309c14321934602b037148cd3756c465/src/modules/gimbal/gimbal.cpp#L568-L569 I found params MNT_MAV_SYSID, MNT_MAV_COMPID are only use for gimbal protocol v1, which not support gimbal device discovering.

In gimbal protocol v2, https://github.dev/PX4/PX4-Autopilot/blob/d5f5c503309c14321934602b037148cd3756c465/src/modules/gimbal/output_mavlink.cpp#L191-L199 PX4 auto discover for gimbal device by gimbal_device_information, so it steal our gimbal device. Of course, we can modify our gimbal device to reject PX4 gimbal_manager message, but can not apply widely. I'd like to hear your thought about this. How would we decide which gimbal device below to which gimbal manager in a complex system with multiple gimbal or multi component want to act as gimbal manager. Currently, mavlink has not have any message field for the gimbal_device to public who is its manager.

Another comment, in our setup, our gimbal manager is successfully integrated with the GCS via standard mavlink GCS <-> gimbal_manger, tested with QGC and our NexGCS. We need integration to PX4, because we want to have manual control via RC input and control in a flight mission with precise control and gps. For now, PX4 support only one gimbal, if PX4 support mount to a gimbal manager, I think there is no meaning to keep PX4's gimbal_manager anymore. How do you think?

return -1;
}

uORB::SubscriptionInterval parameter_update_sub{ORB_ID(parameter_update), 1_s};
thread_running.store(true);
g_thread_data = &thread_data;
Expand Down Expand Up @@ -186,6 +201,13 @@ static int gimbal_thread_main(int argc, char *argv[])

break;

case MNT_MODE_OUT_TO_GIMBAL_MANAGER: //Gimbal manager protocol
thread_data.output_obj = new OutputMavlinkToGimbalManager(params);

if (!thread_data.output_obj) { alloc_failed = true; }

break;

default:
PX4_ERR("invalid output mode %" PRId32, params.mnt_mode_out);
thread_should_exit.store(true);
Expand Down Expand Up @@ -288,9 +310,11 @@ static int gimbal_thread_main(int argc, char *argv[])
thread_data.control_data,
update_result != InputBase::UpdateResult::NoUpdate, thread_data.control_data.device_compid);

// Only publish the mount orientation if the mode is not mavlink v1 or v2
// Only publish the mount orientation if the mode is not MAVLink-based.
// If the gimbal speaks mavlink it publishes its own orientation.
if (params.mnt_mode_out != MNT_MODE_OUT_MAVLINK_V1 && params.mnt_mode_out != MNT_MODE_OUT_MAVLINK_V2) {
if (params.mnt_mode_out != MNT_MODE_OUT_MAVLINK_V1 &&
params.mnt_mode_out != MNT_MODE_OUT_MAVLINK_V2 &&
params.mnt_mode_out != MNT_MODE_OUT_TO_GIMBAL_MANAGER) {
thread_data.output_obj->publish();
}

Expand Down Expand Up @@ -554,6 +578,7 @@ void update_params(ParameterHandles &param_handles, Parameters &params)
param_get(param_handles.mav_sysid, &params.mav_sysid);
param_get(param_handles.mav_compid, &params.mav_compid);
param_get(param_handles.mnt_rate_pitch, &params.mnt_rate_pitch);
param_get(param_handles.mnt_rate_roll, &params.mnt_rate_roll);
param_get(param_handles.mnt_rate_yaw, &params.mnt_rate_yaw);
param_get(param_handles.mnt_rc_in_mode, &params.mnt_rc_in_mode);
param_get(param_handles.mnt_lnd_p_min, &params.mnt_lnd_p_min);
Expand All @@ -578,6 +603,7 @@ bool initialize_params(ParameterHandles &param_handles, Parameters &params)
param_handles.mav_sysid = param_find("MAV_SYS_ID");
param_handles.mav_compid = param_find("MAV_COMP_ID");
param_handles.mnt_rate_pitch = param_find("MNT_RATE_PITCH");
param_handles.mnt_rate_roll = param_find("MNT_RATE_ROLL");
param_handles.mnt_rate_yaw = param_find("MNT_RATE_YAW");
param_handles.mnt_rc_in_mode = param_find("MNT_RC_IN_MODE");
param_handles.mnt_lnd_p_min = param_find("MNT_LND_P_MIN");
Expand All @@ -599,6 +625,7 @@ bool initialize_params(ParameterHandles &param_handles, Parameters &params)
param_handles.mav_sysid == PARAM_INVALID ||
param_handles.mav_compid == PARAM_INVALID ||
param_handles.mnt_rate_pitch == PARAM_INVALID ||
param_handles.mnt_rate_roll == PARAM_INVALID ||
param_handles.mnt_rate_yaw == PARAM_INVALID ||
param_handles.mnt_rc_in_mode == PARAM_INVALID ||
param_handles.mnt_lnd_p_min == PARAM_INVALID ||
Expand Down
15 changes: 9 additions & 6 deletions src/modules/gimbal/gimbal_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,18 @@ namespace gimbal

enum MntModeIn {
MNT_MODE_IN_DISABLED = -1,
MNT_MODE_IN_AUTO, // RC and MAVLink gimbal protocol v2
MNT_MODE_IN_AUTO, // RC and MAVLink gimbal protocol v2
MNT_MODE_IN_RC,
MNT_MODE_IN_MAVLINK_ROI, // MAVLink gimbal protocol v1 (to be deprecated)
MNT_MODE_IN_MAVLINK_DO_MOUNT, // MAVLink gimbal protocol v1 (to be deprecated)
MNT_MODE_IN_MAVLINK_V2 // MAVLink gimbal protocol v2
MNT_MODE_IN_MAVLINK_ROI, // MAVLink gimbal protocol v1 (to be deprecated)
MNT_MODE_IN_MAVLINK_DO_MOUNT, // MAVLink gimbal protocol v1 (to be deprecated)
MNT_MODE_IN_MAVLINK_V2 // MAVLink gimbal protocol v2
};

enum MntModeOut {
MNT_MODE_OUT_AUX = 0,
MNT_MODE_OUT_MAVLINK_V1, // MAVLink gimbal protocol v1 (to be deprecated)
MNT_MODE_OUT_MAVLINK_V2 // MAVLink gimbal protocol v2
MNT_MODE_OUT_MAVLINK_V1, // MAVLink gimbal protocol v1 (to be deprecated)
MNT_MODE_OUT_MAVLINK_V2, // MAVLink gimbal protocol v2
MNT_MODE_OUT_TO_GIMBAL_MANAGER // MAVLink gimbal protocol v2 (mount gimbal manager)
};

struct Parameters {
Expand All @@ -71,6 +72,7 @@ struct Parameters {
int32_t mav_sysid;
int32_t mav_compid;
float mnt_rate_pitch;
float mnt_rate_roll;
float mnt_rate_yaw;
int32_t mnt_rc_in_mode;
float mnt_lnd_p_min;
Expand All @@ -94,6 +96,7 @@ struct ParameterHandles {
param_t mav_sysid;
param_t mav_compid;
param_t mnt_rate_pitch;
param_t mnt_rate_roll;
param_t mnt_rate_yaw;
param_t mnt_rc_in_mode;
param_t mnt_lnd_p_min;
Expand Down
12 changes: 11 additions & 1 deletion src/modules/gimbal/gimbal_params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ parameters:
0: AUX
1: MAVLink gimbal protocol v1
2: MAVLink gimbal protocol v2
3: MAVLink gimbal protocol v2 (mount gimbal manager)
default: 0
min: 0
max: 2
max: 3
reboot_required: true
MNT_MAV_SYSID:
description:
Expand Down Expand Up @@ -158,6 +159,15 @@ parameters:
min: 1.0
max: 90.0
unit: deg/s
MNT_RATE_ROLL:
description:
short: Angular roll rate for manual input in degrees/second
long: Full stick input [-1..1] translats to [-roll rate..roll rate].
type: float
default: 0.0
min: 0.0
max: 90.0
unit: deg/s
MNT_RATE_YAW:
description:
short: Angular yaw rate for manual input in degrees/second
Expand Down
Loading
Loading