Edit 1: Corrected PX4 to Pixhawk 4.
Hi everyone, I’m new here and so far very impressed with the community support I see.
I’ve recently joined on a project that involves giving a golf cart-type vehicle autonomous navigation capabilities (using Pixhawk 4) and unfortunately am at a lack for someone to help guide me through this. I’ll try to be as thorough as possible without being long-winded…
My end goal:
- To control a rover-type vehicle (motor control and steering) programmatically through Python + mavlink scripting, and / or with QGroudControl.
Vehicle details:
- Vehicle (back wheel drive) speed is controlled via a 3.3v PWM signal. I’ve managed to control this using QGC’s motor test sliders. Duty cycle corresponds to speed, as one would expect.
- Steering is via a servo motor controlling the front wheels. Still working on the mechanics behind this but let’s assume this will work out.
- Forward / reverse are controlled by GPIO output + relay. To simplify things let’s assume only forward.
Hardware I have:
- Pixhawk 4
- Pixhawk 4 GPS module
- Sufficient options for power supply
- Raspberry Pi 4 acting as “Companion Computer” (I also have a Jetson Nano / laptop)
- All necessary wires / cables
First thing I’d like to achieve:
- Set vehicle off traveling in a straight line (no steering) for X seconds at Y speed, before coming to a stop. This should be achieved by setting the desired speed via Python script + mavlink command, which will should result in a PWM signal on one of the Pixhawk 4’s PWM pins, whose duty cycle corresponds to the desired speed.
What I’ve tried:
Somewhat blindly (I don’t really know what I’m doing) I have tried passing a command to the Pixhawk 4 with the following script that I finagled together. I’m sure there are plenty of issues:
from dronekit import *
import time
# Initialize connection
vehicle = connect('/dev/ttyUSB0', wait_ready=True, baud=57600)
print("Vehicle connected.") # The connection succeeds
# Set mode
while vehicle.mode.name != "ACRO":
vehicle.mode = VehicleMode("ACRO")
time.sleep(1)
print(vehicle.mode.name)
print(f"Mode set: {vehicle.mode.name}")
while not vehicle.armed :
vehicle.armed = True
print(vehicle.armed)
# Set speed
def send_global_velocity(velocity_x, velocity_y, velocity_z, duration):
msg = vehicle.message_factory.set_position_target_global_int_encode(
0, # time_boot_ms (not used)
0, 0, # target system, target component
mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT_INT, # frame
0b0000111111000111, # type_mask (only speeds enabled)
0, # lat_int - X Position in WGS84 frame in 1e7 * meters
0, # lon_int - Y Position in WGS84 frame in 1e7 * meters
0, # alt - Altitude in meters in AMSL altitude(not WGS84 if absolute or relative)
# altitude above terrain if GLOBAL_TERRAIN_ALT_INT
velocity_x, # X velocity in NED frame in m/s
velocity_y, # Y velocity in NED frame in m/s
velocity_z, # Z velocity in NED frame in m/s
0, 0, 0, # afx, afy, afz acceleration (not supported yet, ignored in GCS_Mavlink)
0, 0) # yaw, yaw_rate (not supported yet, ignored in GCS_Mavlink)
# send command to vehicle on 1 Hz cycle
for x in range(0, duration):
vehicle.send_mavlink(msg)
time.sleep(1)
send_global_velocity(2, 0, 0, 30)
vehicle.armed = False
—> I chose the ACRO mode because it doesn’t require GPS - though I have the GPS module. I am testing this inside so the GPS doesn’t lock, but if a different mode is required I will happily connect the GPS and take things outside.
Results of the above script:
I tested the Pixhawk’s I/O PWM pins with an oscilloscope and found that when I ran the script I received a constant 3.3v signal on pin 3 – which is the same pin that gives a PWM signal when I do the motor test on QGC. This signal no longer appears when I remove vehicle.arm
, and appears to have nothing to do with the rest of the code. The script seems to have no effect.
WHEW.
I hope this makes sense and someone can help me take my first steps at getting this vehicle running. Thanks in advance for any and all help!