Help manual rc control pymavlink(urgent)

Hi
i’m doing my thesis by implementing a controller for the rov and i was looking this code to sett the x,y,z mouvement (An example of using `RC_OVERRIDE`s for basic vehicle control with Pymavlink. Includes a variety of other convenience functions. · GitHub);
i thinked farward,lateral are the mouvement on the x,y axes, but idon´t find the command for the z axis
some one can help me pls (i have no much time left)

in case how can i modify the programm to control the thrusters indipendly in heavy config?

there is some way to see the RCINx inputs of the other 2 truster?

Hi @fusari,

That example is mine - “throttle” is the translation control for the vehicle’s “z” axis.

Per-thruster control is not recommended (because it is only possible in ArduSub via a hacky workaround that disables all safety features), but the ExtendedAutopilot class from the example you’ve linked to should technically be able to do it for a heavy frame vehicle just as easily as a standard BlueROV2 frame vehicle, just with thrusters=8 passed in as an override to the class initialisation. If using the “Servo” approach (as used in the example in the if __name__ == '__main__' section) then you would simply use set_servo commands for thrusters 1-8 instead of 1-6.

Note that normal (motion-axis-based) controls should also work fine for a vehicle using the heavy config, and are preferred because they can actually make use of the control systems and safety features built into ArduSub.

I’m not sure what you mean by this. The get_thruster_outputs function (used in the status_loop function) should automatically show the outputs for the number of thrusters specified in initialisation (which is 6 by default, but you can change to 8 for a heavy config). That’s the servo outputs though.

RCIN is for inputs being sent to the vehicle, and are not currently shown, although if you wanted to look at the values the vehicle is receiving from your program then you could start receiving and displaying the RC_CHANNELS messages.

Hi @EliotBR
i was testing your code but when i try camera_tilt, light command they don´t work
p.s. is possible to send message to start record?

Are you able to successfully control the camera tilt servo and lights levels with a joystick through QGroundControl? I suspect you don’t have them configured correctly in ArduSub’s parameters, in which case ArduSub doesn’t know where they are (or thinks they are connected to a different port to their actual ports), so then it can’t control them when it’s asked to.

yes whit the joistic they works,but whit the python program i have to use the set servo command to controll them

13 for light and 16 for the camera tilt

plus now i have test the program on the water but the motor continuosly stop; is normal? (the motor command is in a while 1)

If it works with the joystick in QGC then they should be configured correctly. How are you trying to control them in Python?

I’m not sure what you mean by “continuously stop”. Is your program sending regular heartbeats? Does your loop have any blocking / sleep points that are long enough to potentially cause a failsafe to trigger due to stopped communication?

If it works with the joystick in QGC then they should be configured correctly. How are you trying to control them in Python?

i was tring to command like

sub.send_rc(lights1 =1500)
sub.send_rc(lights2 =1500)
sub.send_rc(camera_tilt =1100)

I’m not sure what you mean by “continuously stop”. Is your program sending regular heartbeats? Does your loop have any blocking / sleep points that are long enough to potentially cause a failsafe to trigger due to stopped communication?

i mean that the motor mouve for tot sec, after they stop and restart for some sec ect…
the only loop that should block is in the data acquisition (that is in a try) but i don´t think it block the program enought to cause the failsafe; (aniway i will send that part of code to ask some suggestion (sorry for the ita comments))

import time
import sys
from world_body import w2b,b2w

# Import mavutil
from pymavlink import mavutil

V=[0,0,0,0,0,0]		#posizione
Vd=[0,0,0,0,0,0]	#velocita
Vaccw=[0,0,0]		#acc world frame
Vaccb=[0,0,0]		#acc body frame
Vxyzm=[0,0,0]		#acc xyz data
Ti=[0]

def acq_sensor(V,Vd,Ti): 	#da testare

	# Create the connection
	master = mavutil.mavlink_connection('udpin:0.0.0.0:14550')

	# Wait a heartbeat before sending commands
	master.wait_heartbeat()

	# Request all parameters
	master.mav.param_request_list_send(master.target_system, master.target_component)

	V[3]=round(master.messages['ATTITUDE'].roll,2) 								#assegno roll in rad
	V[4]=round(master.messages['ATTITUDE'].pitch,2)  							#assegno pitch
	V[5]=round(master.messages['ATTITUDE'].yaw,2)								#assegno yaw
	Vd[3]=master.messages['ATTITUDE'].rollspeed							#assegno rollspeed
	Vd[4]=master.messages['ATTITUDE'].pitchspeed						#assegno pitchspeed
	Vd[5]=master.messages['ATTITUDE'].yawspeed						#assegno yawspeed

	Tn=master.messages['SYSTEM_TIME'].time_boot_ms*pow(10,-3)						#acq time now [ms]+ conv [ms]>[s]


	while True:
		msg = master.recv_match()
		if not msg:
			continue
		if msg.get_type() == 'RAW_IMU':
			data = str(msg)												#acq stringa whit sensor data

			data = data.split(":")

			Xacc = -int(data[2].split(",")[0])						#acq Xacc body frame

			Yacc = int(data[3].split(",")[0])						#acq Yacc body frame

			Zacc = int(data[4].split(",")[0])						#acq Zacc body frame

			break

	Vaccb[0]=(Xacc)*(9.80665/1000)											#conversione in m/s/s
	Vaccb[1]=(Yacc)*(9.80665/1000)											#conversione in m/s/s
	Vaccb[2]=(Zacc)*(9.80665/1000)											#conversione in m/s/s

	Vaccw=b2w(V,Vaccb)													#from body frame to world frame

	Vaccw[2]=Vaccw[2]+9.80665											#cut gravity component

	

	DT=Tn-Ti[0]															#calcolo variazione di tempo da ultima misura (problema? prima acq valore molto alto)

	Ti[0]=Tn

	Vd[0]=Vd[0]+Vaccw[0]*DT													#calcolo velocità x
	Vd[1]=Vd[1]+Vaccw[1]*DT													#calcolo velocità y
	Vd[2]=Vd[2]+Vaccw[2]*DT													#calcolo velocità z

	V[0]=round(V[0]+Vd[0]*DT+0.5*Vaccw[0]*pow(DT,2),2)									#calcolo posizione x
	V[1]=round(V[1]+Vd[1]*DT+0.5*Vaccw[1]*pow(DT,2),2)									#calcolo posizione y
	V[2]=round(V[2]+Vd[2]*DT+0.5*Vaccw[2]*pow(DT,2),2)									#calcolo posizione z (usare direttamente barometro?)

	return (Xacc,Yacc,Zacc)

p.s. the raw_imu data are filtered yet or are the not filtered? in case were i can find the filtered one?

in particular that happen whit segnal near 1500 like 1525 like

From a quick look I can’t see anything obviously incorrect or blocking in the part of your code that you’ve provided.

The RAW_IMU message is intended to be raw data from the IMU, so should not be filtered. I don’t believe there are filtered accelerometer values available, but the ATTITUDE and AHRS* messages may be of interest for the other values.

Our Basic ESC has a dead-zone at 1500±25ms pulse-durations, so it is expected that the thrusters will not move when any output values within that range are commanded.

I believe that’s intended as a safety measure, to ensure the thrusters only move when commanded to do so, with a bit of tolerance for slight differences in clock rates between each ESC and the hardware providing it with inputs.