"Fly-by-gimbal" > How to control aircraft by 3 axis FPV gimbal direction so aircraft can follow gimbal aiming point?

Hi,

I’m flying an FPV airplane with camera in the nose but without a gimbal. As a result, video feed wobbles in various directions due to wind gusts in my goggles.

I’d like to use a 3-axis FPV gimbal to stabilize the video, similar to how a Parrot Disco or GPS-stabilized-quadrocopter like AVATA-2 with motion controller flies.

The challenge is this:

I am flying in a stabilised cruise mode (+ GPS + pitot + rangefinder). Pixhawk Cube, Ardupilot.

Imagine I want to fly straight ahead (towards 12 o’clock), but the wind is coming from the 9 o’clock direction. As a result, the wing is pushed sideways as it compensates for the wind, flying at an angle instead of directly forward.

I want the gimbal to keep the camera aligned with the intended flight direction, so I’m controlling the wing’s flight path based on the gimbal’s orientation, rather than the plane’s own tilted fuselage position.

Is there any solution / code available to make it work so that the airplane compensates for wind automatically and I can essentially fly-by-wire fly by gimbal?

I assume I need to somehow add/find a code to detect the gimbal direction relative to aircraft position and set max limits for sideways flight…

Blockquote

Here’s a clearer breakdown of how this system can work:

  1. Gimbal Data Feed: The gimbal constantly sends its orientation data (pitch, roll, yaw) to the flight controller. The gimbal itself adjusts its position to stabilize the camera or maintain a specific view. The orientation data from the gimbal is then used by the flight controller to control the aircraft. For example, when you tilt the gimbal down using the RC stick, the aircraft will descend. When you tilt the gimbal to the right, the aircraft will turn right. If the gimbal is centered in a neutral position, the aircraft will fly straight along the center of the video feed.
  2. Flight Controller Adjustment: The flight controller processes the gimbal’s orientation data and adjusts the aircraft’s flight controls (yaw, roll, pitch, and minimum airspeed) to ensure the aircraft’s flight path aligns with the gimbal’s direction, with wind compensation factored in.
  3. Dynamic Adjustment: As the gimbal continuously updates its orientation, the flight controller makes real-time adjustments to the aircraft’s attitude. For example, if the gimbal turns left, the aircraft will automatically adjust its yaw to match, ensuring the aircraft’s flight path stays in sync with the gimbal’s movement.

In essence, the aircraft will follow the direction the gimbal is pointing, without requiring manual control of the aircraft’s attitude. The pilot controls the gimbal’s orientation, and the aircraft adapts its flight path accordingly.

To summarize, the flight controller essentially “mirrors” the gimbal’s movements, making the aircraft fly as if it’s “following” the gimbal’s direction.


What I got so far:

Configuring the Gimbal:

  • In Mission Planner or ArduPilot’s ground station software, configure the gimbal’s control channels. This involves setting up the servo outputs (or serial/i2c if applicable) that control the pitch, roll, and yaw of the gimbal.
  • Ensure that the gimbal’s orientation feedback is configured to send data back to the Pixhawk. This can be done via the MAVLink protocol, or if using PWM, ensure the proper range and settings are configured.

Set Up Gimbal Autonomy:

  • In ArduPilot, use the Gimbal Control feature to integrate the gimbal with the flight controller’s autopilot mode. This allows you to control the gimbal’s orientation (for instance, using your RC controller to adjust the gimbal’s position and have the aircraft follow it).
    • Set the Gimbal Control Mode (GCS_Gimbal_Control).
    • Map the gimbal’s orientation control (pitch, roll, yaw) to an RC channel or through a control interface.

Adjusting Aircraft Flight Path Based on Gimbal Orientation

  • Configure the Pixhawk’s Flight Control Modes (e.g., STABILIZE, LOITER, AUTO) to respond to changes in the gimbal’s orientation. For example:
    • If the gimbal is tilted down, you want the aircraft to descend.
    • If the gimbal is rotated left or right, the aircraft should turn in the same direction.
  • In Mission Planner, use the “Follow Me” feature (if available) or create a custom mission script that adjusts the aircraft’s yaw, pitch, and roll based on the gimbal’s orientation.

Dynamic Gimbal Flight Path Coordination:

  • This feature is where ArduPilot’s integration with the gimbal becomes key. When the gimbal is controlled via the RC stick or through autonomous commands:
    • The Pixhawk flight controller processes the gimbal’s orientation.
    • It dynamically adjusts the aircraft’s flight controls (yaw, pitch, roll) to match the gimbal’s direction.
    • The aircraft will follow the gimbal’s direction as if it were “mirroring” its movement in real-time.

For example: - Gimbal Tilt Down (Pitch) → Aircraft Descends. - Gimbal Tilt Left (Yaw) → Aircraft Yaws Left. - Gimbal Tilt Right (Yaw) → Aircraft Yaws Right. - Gimbal Neutral Position (Pitch and Yaw centered) → Aircraft Flies straight ahead.

Autonomous Flight and Gimbal Control

  • In Mission Planner or ArduPilot, you can write custom waypoint missions or use the Follow-Me functionality to have the aircraft follow a predefined path while the gimbal maintains the camera’s orientation.
  • You can also integrate the use of GPS waypoints where the gimbal adjusts automatically to point towards a specific area or object (e.g., following a subject of interest).

import time
from pymavlink import mavutil

# Connect to the Pixhawk (adjust the connection string as per your setup)
# For serial connection: "/dev/ttyUSB0" or "/dev/ttyACM0" for Linux, COM3 for Windows, etc.
# For UDP: "udp:127.0.0.1:14550" or whatever your Pixhawk's UDP address is.
master = mavutil.mavlink_connection('udp:127.0.0.1:14550')

# Function to send gimbal orientation commands
def send_gimbal_orientation(pitch, roll, yaw):
    # Create a MAVLink gimbal control message
    master.mav.gimbal_control_send(
        0,                 # Target system (0 means all systems)
        0,                 # Target component (0 means all components)
        pitch,             # Pitch (gimbal tilt, in degrees, -90 to +90)
        roll,              # Roll (gimbal roll, in degrees, -180 to +180)
        yaw,               # Yaw (gimbal yaw, in degrees, -180 to +180)
        1,                 # Mode (1 = Absolute, 2 = Relative)
        0                  # Disabling the 'stabilize' flag (0 = no stabilization)
    )

# Function to adjust flight attitude based on gimbal orientation
def adjust_aircraft_attitude(pitch, roll, yaw):
    # You could send similar MAVLink commands to adjust the aircraft's attitude based on the gimbal's orientation.
    # For example, using attitude control commands to adjust pitch, roll, and yaw.
    
    # Send MAVLink command to adjust aircraft attitude
    master.mav.set_attitude_target_send(
        0,                # Target system
        0,                # Target component
        1,                # Time boot_ms (set to 1 for simplicity)
        0b00000100,       # Type mask (for setting pitch, roll, and yaw, no other control)
        pitch,            # Roll (set aircraft roll to match gimbal's pitch)
        roll,             # Pitch (set aircraft pitch to match gimbal's roll)
        yaw,              # Yaw (set aircraft yaw to match gimbal's yaw)
        0                 # Throttle (set to 0 as we are not controlling throttle)
    )

# Main loop
def main():
    # The gimbal's current orientation (example values in degrees)
    gimbal_pitch = 10  # Gimbal tilt angle (pitch)
    gimbal_roll = 5    # Gimbal roll angle
    gimbal_yaw = 30    # Gimbal yaw angle

    while True:
        # Send gimbal orientation commands
        send_gimbal_orientation(gimbal_pitch, gimbal_roll, gimbal_yaw)
        
        # Adjust aircraft's flight path based on gimbal's orientation
        adjust_aircraft_attitude(gimbal_pitch, gimbal_roll, gimbal_yaw)

        # Sleep for a short duration before the next loop (for example, 1 second)
        time.sleep(1)

if __name__ == "__main__":
    main()


Code Breakdown:

  1. MAVLink Connection:
  • The script uses the mavutil.mavlink_connection() function to establish a connection with the Pixhawk via a UDP (or serial) link. The connection string should be updated depending on your setup. For example, you might connect over a serial port (/dev/ttyACM0 for Linux or COM3 for Windows), or via UDP to the Pixhawk.
  1. Gimbal Control Command (send_gimbal_orientation):
  • The send_gimbal_orientation() function sends a gimbal control message to Pixhawk using master.mav.gimbal_control_send().
  • This message sets the gimbal’s pitch, roll, and yaw. You can adjust these values to control the gimbal’s orientation, which will influence the aircraft’s flight path.
  1. Aircraft Attitude Adjustment (adjust_aircraft_attitude):
  • The adjust_aircraft_attitude() function sends a set_attitude_target command to Pixhawk to adjust the aircraft’s flight attitude based on the gimbal’s orientation.
  • The function uses the mavutil.mavlink_connection.set_attitude_target_send() method, which allows the Pixhawk to adjust its pitch, roll, and yaw in response to the gimbal’s orientation.
  1. Main Loop:
  • The main() function runs in an infinite loop, sending updated gimbal orientation data to Pixhawk every second. You can adjust the timing of the loop depending on your needs (e.g., every 100ms or 1 second).
  • Gimbal angles (pitch, roll, yaw) are passed to both the gimbal control and the aircraft attitude adjustment functions.

IMHO this can be done with onboard Lua.

1 Like

Thanks for reply!

Is there maybe any particular approach that you recommend?

I have a sample code:


function update()
    -- Get gimbal orientation data (assuming pitch, roll, yaw)
    local gimbal_pitch = -- obtain pitch data from gimbal
    local gimbal_yaw = -- obtain yaw data from gimbal

    -- Map gimbal pitch to aircraft pitch or altitude control
    if gimbal_pitch < threshold_down then
        -- Command aircraft to descend or pitch down
    elseif gimbal_pitch > threshold_up then
        -- Command aircraft to ascend or pitch up
    end

    -- Map gimbal yaw to aircraft yaw control
    if gimbal_yaw < threshold_left then
        -- Command left yaw
    elseif gimbal_yaw > threshold_right then
        -- Command right yaw
    end

    -- Adjust aircraft roll based on gimbal orientation if necessary
    -- You may add roll compensation here if needed

    -- Loop the function
    return update, 100 -- Run every 100 ms
end

return update()