Raspberry pi and Attitude adjustment

HELLO! Everyone.
I want use raspberry pi to extract the data of pitch and roll,so i can use the angle data to control stepper motor . The motor drive the ball screw,then the weight will move to balance ROV.
The first step is extract the angle data.I am not good at programming.Can someone tell me this part of the code?

Hi @Richard1, welcome to the forum :slight_smile:

It’s a bit unclear to me what you’re trying to do here. You’ve mentioned you’re wanting to adjust your ROV balance with a linear actuator like a ball screw, so presumably you’re not using a standard BlueROV2. What kind of electronics setup are you using? If it’s our Advanced ROV Electronics Package you can potentially use pymavlink on the Raspberry Pi companion computer to read the relevant telemetry mavlink messages from the Pixhawk.


Of course i use raspberry 3b and pixhawk as hardware.Related debugging has been completed.Thrusters、led and camera are running well.QGC is also running well.

Now I want to write script that can collect angle information and control the stepper motor to raspberry pi .Once angle changes,linear actuator will run.I use this method to maintain ROV balance.

So at first ,i need to extract the data of pitch and roll from pixhawk. So can you tell me what should i do about this part?I am learning python and raspberry pi,I am also getting to know pymavlink.But i’m a little confused about them. :thinking:

Hi, Check our request message interval example. It requests attitude messages at a given interval.

You can additionally use master.recv_match(type='ATTITUDE') to print only ATTITUDE messages.

Hi,Can you tell me specifically what should I do in this interface to get attitude.
And do I have to have a GUI of raspberry pi?Do I have to download the pymavlink library and upgrade python?

No, you don’t need a GUI for the Raspberry Pi

Pymavlink should already be installed. If you enter python in the console it should take you into an interactive python prompt, where you should be able to do things like from pymavlink import mavutil.

To get attitude you can follow the run pyMavlink on companion computer example that I linked to in my first response, but using the type='ATTITUDE' filter that @williangalvani suggested. You can either run that code in the interactive prompt I mentioned earlier, or save it as a .py file (probably best to put such a file in ~companion/tools) and run it using python filename.py (press CTRL+C when you want to exit out from the endless printing loop that it will go into, and type quit() to exit the interactive python prompt if you’re finished with it).

Once you’ve got code in a .py file that does what you want you can add a suitable line to the file ~/companion/.companion.rc to start it. If you start it as a named screen session like the existing ones then it will also be listed as one of the ‘Active Services’ in the companion web-interface System page.

If you haven’t worked with the raspberry pi terminal interface before then you should look up how to use a bash terminal (particularly useful commands are ls, cp, mv, and rm). You can use the nano or vi programs to create or modify files - nano is easier to use for beginners and lists the relevant commands for saving and exiting in the interface, while vi is more powerful but has a harder learning curve.

I think there must be other things that need to be changed.
And i want to keep printing the message.Can you show me the code?
If i want to get attitude on the PC,is the code the same?
ATTITUDE.txt (553 Bytes)
This is my code.

IndentationError means there’s an error in your indentation. The text file you sent has an extra space before the word message - the first line after the try: statement.

You’re also trying to extract ‘param_id’ and ‘param_value’ from the message that you receive, which doesn’t make sense. Which parameters do you want?

Your current code connects using an old interface, and connects to port 14550, which is what you expect to connect to on the surface computer (see the connecting on the surface computer example). If you look at the companion example I linked you to in my first message it connects to port 9000 using udpout, and also has a different structure for the rest of the file.

We can’t do your development work for you, so generally can’t just produce code files on demand. In this case it’s a very minor modification of existing examples that we’ve already linked you to, so here’s the code for connecting from the surface computer (the PC you referred to):

"""
TOP COMPUTER:
  Example of how to connect pymavlink to an autopilot via an UDP connection
"""
import time
# Import mavutil
from pymavlink import mavutil

# Create the connection
#  If using a companion computer
#  the default connection is available
#  at ip 192.168.2.1 and the port 14550
# Note: The connection is done with 'udpin' and not 'udpout'.
#  You can check in http:192.168.2.2:2770/mavproxy that the communication made for 14550
#  uses a 'udpbcast' (client) and not 'udpin' (server).
#  If you want to use QGroundControl in parallel with your python script,
#  it's possible to add a new output port in http:192.168.2.2:2770/mavproxy as a new line.
#  E.g: --out udpbcast:192.168.2.255:yourport
master = mavutil.mavlink_connection('udpin:0.0.0.0:14550')

# Confirm connection has been made
master.wait_heartbeat()

print("Receiving telemetry information - press CTRL+C to stop the loop")

# Get some information !
while True:
    try:
        message = master.recv_match(type='ATTITUDE', blocking=True).to_dict()
        print("\nfull message:")
        print(message)
        print("extracting part of the message:")
        print("pitch: %d, roll: %d" % (message['pitch'], message['roll']))
    except Exception:
        pass
    time.sleep(0.1)

To do the same thing on the companion computer you’ll need to refer to the companion example.

Hi,I ran the code on PC.It looks like the code is not working.I search attitude、pitch and roll in ‘mavutil.py’,but i can’t found it.Is type=‘ATTITUDE’ right? If so,what is problem?
(I connect pi and pix,and i can see the attitude on QGC)

Are you getting any errors in particular? I’ve just edited the code to add a master.wait_heartbeat() call to ensure the connection is actually being made.

Note that QGC also uses port 14550, so you should be running this pymavlink script when QGC is closed, or at least not connected to the ROV.

I turn off the QGC and add master.wait_heartbeat(). Code shows no errors but do not display attitude information. It shows ‘Connected to pydev debugger (build 211.7442.45)’.
I think it can connect to the port.So there must be a problem in the second half of the code.
Can you use this code to get attitude information?
ATTITUDE.txt (427 Bytes)

That works fine for me.

Can you try running the following code and seeing where it gets up to?

import time
from pymavlink import mavutil
print('Imports complete')

master = mavutil.mavlink_connection('udpin:0.0.0.0:14550')
print('master created')

master.wait_heartbeat() 
print('heartbeat confirmed')

message = master.recv_match(type='ATTITUDE', blocking=True)
print('message detected')
message_dict = message.to_dict()
print('dictionary created')
print(message)
print('getting pitch:')
print(message['pitch'])
print('getting roll:')
print(message['roll'])

Connected to pydev debugger (build 211.7442.45)
Imports complete
master created
The above is the output of the program.It seems that there is a problem with the heartbeat.

wait_heartbeat is a blocking call, and if your companion computer isn’t connected correctly to your top computer then your script will never receive a heartbeat, so it just waits there forever. Can you try connecting to QGroundControl, then closing QGroundControl and trying to run your script directly afterward?

Also, can you confirm which version of the companion software you’re using? It should be visible at the top left of the companion web interface.

I do as you said,but the result is still the same.My version of the companion software is 0.0.22.
I see the example of run pyMavlink on the surface computer doesn’t need 'master.wait_heartbeat() '.
Will the problem be here?

Would you be able to update to the latest stable companion software version, from the web interface System page? There was a change in 0.0.23 which changed the autopilot to using mavlink version 2 by default, which could possibly be causing the issue you’re having.

I’m currently updating that documentation to include one. Every mavlink-connected device should generally be able to see heartbeats from the others in the same system, and making sure that a heartbeat is available is a good way of confirming whether a connection has actually been made. I’ve checked with three operating systems on my surface computer and they’re all correctly detecting the heartbeat :slight_smile:

My version of the companion softwarehas been updated to 0.0.26.
The result is still the same.It can’t detect the heartbeat.
I think my development environment is ok,because the the program can run.
I correctly connected the hardware and i can visit http://192.168.2.2:2770.
When i use QGC,i can see attitude.
When i run the code,I turn off QGC.
So is there anything else I didn’t pay attention to?
The following is a screenshot of the program and web page.


Your MAVProxy options seem to be the same as mine.

Possibly you need to allow python through your firewall (the same way as for QGC) so it can access the udp stream? I’d suggest restarting pycharm after that and running again.

This is indeed a firewall problem.
Well,thank you very much,Eliot.Through your help and my study and debugging,finally i can see attitude.
But the data is a bit strange.When my pitch is 90 degrees,the result of running the program is about plus or minus1.5.Is it feasible for me to multiply it by 60 to get the angle information when processing the result?
5~TPAUV)UDA316{@I_J0PQ

Glad that’s sorted then :slight_smile:

The mavlink common messages documentation for the ATTITUDE message states that the angles are in radians, between \pm \pi. There are 2\pi radians in a circle, and 360 degrees in a circle, so to convert radians to degrees you can either use the conversion formula degrees = radians \times \frac{180}{\pi}, or you can use the degrees function from Python’s math builtin module (for a single value), or the numpy library (for an array of multiple values). Note that 180/\pi =57.2957..., so your guess of 60 wasn’t too far off the true conversion :slight_smile: