Hi, @tony-white!
I tried to create an example of what I am trying to do:
class MAVLinkTest:
def __init__(self):
# Define initial parameters #
self.num_thrusters = 8
self.loop_time = 5.0 # seconds
self.action = 1530
self.active = True
# Create a ROS node #
rospy.init_node('mavlink_actions_test_node', anonymous=False)
# Define the loop rate #
rospy.Rate(1000)
# Create the connection with Kame #
self.master = mavutil.mavlink_connection('udp:192.168.2.1:14550')
# Make sure the connection is valid #
self.master.wait_heartbeat()
print('Connection established!!!')
# Initialize the thread #
self.keeper_thread = threading.Thread(target=self._keeper_loop, daemon=True)
self.keeper_thread.start()
# Wait until arming confirmed #
print("Waiting for the vehicle to arm...")
self.master.motors_armed_wait()
print('Armed!')
# Set the rate of the SERVO_OUTPUT_RAW message #
self.request_message_interval(50)
time.sleep(2)
# Set the thrusters to autonomous mode #
self.set_thrusters_mode()
self.set_thrusters_mode('autonomous')
def _keeper_loop(self):
while self.active:
self.servo_outputs = self.master.recv_match(type='SERVO_OUTPUT_RAW', blocking=True)
def request_message_interval(self, frequency_hz: float):
self.master.mav.command_long_send(
self.master.target_system,
self.master.target_component,
mavutil.mavlink.MAV_CMD_SET_MESSAGE_INTERVAL,
0,
mavutil.mavlink.MAVLINK_MSG_ID_SERVO_OUTPUT_RAW, # The MAVLink message ID
1e6 / frequency_hz, # The interval between two messages in microseconds. Set to -1 to disable and 0 to request default rate.
0, 0, 0, 0, # Unused parameters
0, # Target address of message stream (if message has target address fields). 0: Flight-stack default (recommended), 1: address of requestor, 2: broadcast.
)
# Function to set motors to autonomous mode #
def set_thrusters_mode(self, mode='normal'):
for thruster_index in range(self.num_thrusters):
if mode == 'autonomous':
self.master.mav.param_set_send(self.master.target_system,
self.master.target_component,
("SERVO" + str(thruster_index+1) + "_FUNCTION\0").encode(),
0,
mavutil.mavlink.MAV_PARAM_TYPE_INT32)
elif mode == 'normal':
self.master.mav.param_set_send(self.master.target_system,
self.master.target_component,
("SERVO" + str(thruster_index+1) + "_FUNCTION\0").encode(),
33+thruster_index,
mavutil.mavlink.MAV_PARAM_TYPE_INT32)
# Function to send a PWM command to a thruster #
def thruster_cmd(self, servo_id):
cmd = self.master.mav.command_long_encode(
self.master.target_system,
self.master.target_component,
mavutil.mavlink.MAV_CMD_DO_SET_SERVO,
0,
servo_id,
self.action,
0,0,0,0,0
)
# Send the command to the thruster #
self.master.mav.send(cmd)
def finish_test(self):
# Return the thrusters to normal mode #
self.set_thrusters_mode()
# Stop the thread cleanly #
self.active = False
self.keeper_thread.join()
def run(self):
loop_start_time = time.time()
while (time.time() - loop_start_time) < self.loop_time:
# Change the action #
self.action += 2
# Send the action to the thrusters #
action_start_time = time.time()
for i in range(8):
thr_id = i + 1
self.thruster_cmd(thr_id)
action_send_time = time.time()
print(f"Send time -> {np.around(action_send_time - action_start_time, 4)}")
while True:
count_check = 0
# Request the SERVO_OUTPUT_RAW message #
if self.servo_outputs is not None:
servo_outputs = self.servo_outputs.to_dict()
thruster_outputs = [servo_outputs[f'servo{i+1}_raw'] for i in range(self.num_thrusters)]
# Check if the action was applied in the thrusters #
for i in range(8):
thr = thruster_outputs[i]
if (int(self.action) - 1 < int(thr) < int(self.action) + 1):
count_check += 1
if count_check == 8:
break
action_apply_time = time.time()
print(f"Apply time -> {np.around(action_apply_time - action_send_time, 4)}")
print()
# Finish the test #
self.finish_test()
if __name__ == '__main__':
# Initialize the test #
mavlink_test = MAVLinkTest()
# Run the test #
mavlink_test.run()
I checked your suggestions and increased the loop time. However, my apply_time is still considerable and superior to 0.2 s, which is too much for me. Do you think there is a way of reducing this time? Preferably the 0.1 s you talked about.
Thank you very much for the attention!