thecognifly / yamspy Goto Github PK
View Code? Open in Web Editor NEWYet Another Multiwii Serial Protocol Python Interface... for Betaflight, iNAV, etc...
Home Page: https://thecognifly.github.io/
License: GNU General Public License v3.0
Yet Another Multiwii Serial Protocol Python Interface... for Betaflight, iNAV, etc...
Home Page: https://thecognifly.github.io/
License: GNU General Public License v3.0
Hi Ricardo,
Hope all is good, I had to take a step our for a while... but now I am back and will update regarding gpiozero etc.
I wanted to ask a quick question - I've changed the drone's firmware form betaflight to INAV.
The problem that the drone is not arming when I press the associated key.
I think that the problem is that "arming" is associated with "Aux1" while in INAV configurator arming is associated with "ch5". The drone can be armed via RC (Taranis X9 lite).
I've tried to change "aux1" to "ch5" or "CH5".
What do you think?
John
So I recently had to get a new SD card with Raspbian because my old one stopped working for some reason. I downloaded the most recent versions of the linux kernel and python-evdev, and when I run jstest the event values are between -32765 and 32765, or thereabouts, as opposed to 0-255. When I move the sticks, the event values change as expected. However, when I run the joystick-async.py script, nothing happens when I move the stick. I altered the code values to work with the new event values, but still nothing. I inserted a print statement into the code, but moving the sticks does nothing, for the event values, or the RC commands. What should I do? Should I just revert to an older version of the python-evdev package and the linux kernel? Or do I need to configure python-evdev somehow?
Documentation for MSP codes missing in codeline 64 in init.py
Link expired https://git.io/fjRAa
Where can I find the new documentaion?
Hi, I'm comparing altitude reading from MSP and one I see in OSD. In static position they match move when I move drone the altitude increases, but slowly climbing back to 0 so that when I put the quad down it becomes negative and starts increasing. Any ideas what's happening?
Maybe parsing is wrong and "vario" affects reading?
Hello Ricardo,
Hope all is good :)
I've tried with gpizero and it looks nice but would like to try and use the code without keyboard.
So, for that I wrote a new main function without a loop where I use YAMSPy as following:
board = MSPy(device="/dev/ttyAMA0", loglevel='WARNING', baudrate=115200)
board.enter()
print('after connection')
CMDS = {'roll':1500,'pitch':1500,'throttle': 900,'yaw':1500,'CH5':2000,'aux2':1000}
CMDS_ORDER = ['roll', 'pitch', 'throttle', 'yaw', 'CH5', 'aux2']
if board.send_RAW_RC([CMDS[ki] for ki in CMDS_ORDER]):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
print('after commands')
The value of CH5 (2000) is configured to arm the drone.
When I use the regular simpleUI script the drone is armed, but when I use the modified script I see in INAV configurator that CH5 indeed is changed to 2000 but the drone is not armed.
The only difference is the loop.
What do you think?
Beast regards and stay healthy!
John
Hi,
I'm trying to send GPS data through MSP to an FC with betaflight (the current latest version). I'm using code MSP_SET_RAW_GPS
that according to this it sets a set of GPS observables. I show below an example of a code I'm using that sends PS4 controller commands for roll, pitch, yaw, and throttle, followed by an attempt to send the GPS data as well. My problem is that the GPS section is not working. For some reason, it freezes the loop. Any idea why is not working?
Note that I'm using betaflight because it allows setting MSP GPS mode, which I believe is to work precisely as I'm trying to do.
import time
from yamspy import MSPy
from approxeng.input.selectbinder import ControllerResource
serial_port = "/dev/serial0"
FC_SEND_LOOP_TIME = 0.05
CMDS_ORDER = ['roll', 'pitch', 'throttle', 'yaw', 'aux1', 'aux2']
CMDS = {
'roll': 1500,
'pitch': 1500,
'yaw': 1500,
'aux1': 1000,
'aux2': 1000
}
def stick2pwm(x):
return int(200*x)
with MSPy(device=serial_port, loglevel='WARNING', baudrate=115200) as board:
command_list = ['MSP_API_VERSION', 'MSP_FC_VARIANT', 'MSP_FC_VERSION', 'MSP_BUILD_INFO',
'MSP_BOARD_INFO', 'MSP_UID', 'MSP_ACC_TRIM', 'MSP_NAME', 'MSP_STATUS',
'MSP_STATUS_EX','MSP_BATTERY_CONFIG', 'MSP_BATTERY_STATE', 'MSP_BOXNAMES']
for msg in command_list:
if board.send_RAW_msg(MSPy.MSPCodes[msg], data=[]):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
try:
with ControllerResource() as joystick:
while joystick.connected:
#lx -> ga_0
#ly -> ga_1
#rx -> ga_2
#ry -> ga_3
lx,ly,rx,ry,triangle,rt,lt = joystick['lx','ly','rx','ry','triangle','rt','lt']
throttle = ly
yaw = lx
roll = rx
pitch = ry
if throttle > 0:
CMDS['throttle'] = 1000+stick2pwm(throttle)
else:
CMDS['throttle'] = 1000
if yaw > 0:
CMDS['yaw'] = 1500+stick2pwm(yaw)
elif yaw < 0:
CMDS['yaw'] = 1500+stick2pwm(yaw)
else:
CMDS['yaw'] = 1500
if roll > 0:
CMDS['roll'] = 1500+stick2pwm(roll)
elif roll < 0:
CMDS['roll'] = 1500+stick2pwm(roll)
else:
CMDS['roll'] = 1500
if pitch > 0:
CMDS['pitch'] = 1500+stick2pwm(pitch)
elif pitch < 0:
CMDS['pitch'] = 1500+stick2pwm(pitch)
else:
CMDS['pitch'] = 1500
if rt > 0.9 and CMDS['aux1'] < 1500:
CMDS['aux1'] = 1800
elif lt > 0.9 and CMDS['aux1'] > 1500:
CMDS['aux1'] = 1000
#send cmds to FC
CMDS_RC = [CMDS[ki] for ki in CMDS_ORDER]
if board.send_RAW_RC(CMDS_RC):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
############ SEND GPS DATA #############
gps_fix = 1
gps_numSat = 7 #num_sat
gps_lat = int(3843.037537*10000000) #lat
gps_lon = int(00907.745287*10000000) #lon
gps_alt = int(89.2*100) #altitude
gps_spe = int(0.0) #spd_over_grnd
gps_grd_cou = int(74.6*10) #true_course
# gps_hdop = int(1.0*100)
data_gps = board.convert([gps_fix], 8)
data_gps += board.convert([gps_numSat], 8)
data_gps += board.convert([gps_lat], 32)
data_gps += board.convert([gps_lon], 32)
data_gps += board.convert([gps_alt], 16)
data_gps += board.convert([gps_spe], 16)
# data_gps += board.convert([gps_grd_cou], 16)
if board.send_RAW_msg(MSPy.MSPCodes['MSP_SET_RAW_GPS'], data=data_gps):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
#######################################
time.sleep(FC_SEND_LOOP_TIME)
except KeyboardInterrupt:
print("stop")
CMDS = {
'roll': 1500,
'pitch': 1500,
'yaw': 1500,
'aux1': 1000,
'aux2': 1000
}
CMDS_RC = [CMDS[ki] for ki in CMDS_ORDER]
if board.send_RAW_RC(CMDS_RC):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
pass
Thanks @ricardodeazambuja for the useful code.
My ports setup
I run the example code simpleUI.py
, the result is like this
Press 'q' to quit, 'r' to reboot, 'm' to change mode, 'a' to arm, 'd' to disarm and arrow keys to control
ARMED: False armingDisableFlags: ['RXLOSS', 'ANGLE', 'MSP']
cpuload: 31 cycleTime: 249
mode: 0 Flight Mode: []
Battery Voltage: 0.01V VOLTAGE TOO HIGH
Motor Values: [1000, 1000, 1000, 1000, 0, 0, 0, 0]
RC Channels Values: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
GUI cycleTime: 18.98ms (average 74.16Hz)
apiVersion: 1.45.0 flightControllerIdentifier: BTFL
flightControllerVersion: 4.4.3 boardIdentifier: S411
boardName: JHEF411 name:
If I select the ARM/DISARM
command, it’s as if the command is not being sent, and I have questions in the RX
input of my flight controller.
Sending Arm command...
ARMED: False
or
Sending Disarm command...
ARMED: False
Armed never changes, as if the command does not reach the flight's microcontroller.
But when I select the REBOOT
command, the pilot reboots.
I don’t yet have enough knowledge in betaflight firmware, as far as I understand, the ARM
flag appears in three cases:
1. When there is no connection with the receiver(pult)
2. When the accelerometer sensor does not show the horizon, it is not calibrated/aligned
3. There is no connection via the MSP
protocol
I don't have a pult/control panel, ESC board, battery or motors.
How is it possible to put into operation a “naked” flight controller without peripherals?
Currently it just print stuff on the screen and that is pretty annoying. simpleUI uses curses and it's much easier to test things that way.
Hi,
Can't run any of the examples. For example, read_altitude.py example gives the error:
AssertionError: There's something wrong with the serial connection... check the logfile!
But the serial connection is working. The log file:
[DEBUG] [2021-09-08 10:56:05,496]: RAW message sent: bytearray(b'$M<\x00\x01\x01')
[DEBUG] [2021-09-08 10:56:05,499]: State: 0 - byte received (at 1631094965.4989734): 36
[DEBUG] [2021-09-08 10:56:05,499]: State: 1 - byte received (at 1631094965.4989734): 77
[DEBUG] [2021-09-08 10:56:05,499]: State: 2 - byte received (at 1631094965.4989734): 62
[DEBUG] [2021-09-08 10:56:05,499]: State: 3 - byte received (at 1631094965.4989734): 3
[DEBUG] [2021-09-08 10:56:05,499]: State: 4 - byte received (at 1631094965.4989734): 1
[DEBUG] [2021-09-08 10:56:05,499]: State: 7 - byte received (at 1631094965.4989734): 0
[DEBUG] [2021-09-08 10:56:05,500]: State: 8 - byte received (at 1631094965.4989734): 1
[DEBUG] [2021-09-08 10:56:05,500]: State: 8 - byte received (at 1631094965.4989734): 44
[DEBUG] [2021-09-08 10:56:05,500]: State: 9 - byte received (at 1631094965.4989734): 47
[DEBUG] [2021-09-08 10:56:05,500]: Message received (length 3) - Code 1
[DEBUG] [2021-09-08 10:56:05,500]: RAW message sent: bytearray(b'$M<\x00\x0
```2\x02')
[DEBUG] [2021-09-08 10:56:05,509]: State: 0 - byte received (at 1631094965.5091374): 36
[DEBUG] [2021-09-08 10:56:05,509]: State: 1 - byte received (at 1631094965.5091374): 77
[DEBUG] [2021-09-08 10:56:05,509]: State: 2 - byte received (at 1631094965.5091374): 62
[DEBUG] [2021-09-08 10:56:05,509]: State: 3 - byte received (at 1631094965.5091374): 4
[DEBUG] [2021-09-08 10:56:05,509]: State: 4 - byte received (at 1631094965.5091374): 2
[DEBUG] [2021-09-08 10:56:05,509]: State: 7 - byte received (at 1631094965.5091374): 66
[DEBUG] [2021-09-08 10:56:05,510]: State: 8 - byte received (at 1631094965.5091374): 84
[DEBUG] [2021-09-08 10:56:05,510]: State: 8 - byte received (at 1631094965.5091374): 70
[DEBUG] [2021-09-08 10:56:05,510]: State: 8 - byte received (at 1631094965.5091374): 76
... (quite big)
[DEBUG] [2021-09-08 10:56:05,595]: Message received (length 22) - Code 101
[DEBUG] [2021-09-08 10:56:05,595]: RAW message sent: bytearray(b'$M<\x00\x96\x96')
[DEBUG] [2021-09-08 10:56:05,600]: State: 0 - byte received (at 1631094965.6009123): 36
[DEBUG] [2021-09-08 10:56:05,601]: State: 1 - byte received (at 1631094965.6009123): 77
[DEBUG] [2021-09-08 10:56:05,601]: State: 2 - byte received (at 1631094965.6009123): 62
[DEBUG] [2021-09-08 10:56:05,601]: State: 3 - byte received (at 1631094965.6009123): 22
[DEBUG] [2021-09-08 10:56:05,601]: State: 4 - byte received (at 1631094965.6009123): 150
[DEBUG] [2021-09-08 10:56:05,603]: State: 7 - byte received (at 1631094965.6009123): 46
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 1
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 33
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,603]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 65
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 3
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,604]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,605]: State: 8 - byte received (at 1631094965.6009123): 26
[DEBUG] [2021-09-08 10:56:05,605]: State: 8 - byte received (at 1631094965.6009123): 4
[DEBUG] [2021-09-08 10:56:05,605]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,605]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,605]: State: 8 - byte received (at 1631094965.6009123): 1
[DEBUG] [2021-09-08 10:56:05,605]: State: 8 - byte received (at 1631094965.6009123): 0
[DEBUG] [2021-09-08 10:56:05,605]: State: 9 - byte received (at 1631094965.6009123): 211
[DEBUG] [2021-09-08 10:56:05,605]: Message received (length 22) - Code 150
Hi,
I saw that the device is written as "tty/..." can I write an IP address instead? so I will transmit the command to ESP module that is on the drone (the ESP is just a bridge) or am I missing something in the setup?
Thanks
Hello, I am trying to make a otonom drone without person control. Rashperry pi will send images to computer and I will process that image in computer. After that computer send command to raspberry pi. And raspberry pi send command to omnibus for motors. I have a problem about betaflight and MSP. We tried a lot of things but we still have problems. Betaflight supported our controller, we can get data by using usb port. We are trying to use raspberry pi4 and UART6(on flight controller). We couldn't do it "MSP RX input" configuration. Therefore, when using raspberry, we cannot receive the data like when using the usb port.
I running inav 2.3
And crashing running read_adtitude.py it looks like data is being readed.
MSPy.log
Traceback (most recent call last):
File "read_altitude.py", line 45, in
with MSPy(device=serial_port, loglevel='DEBUG', baudrate=115200) as board:
File "/usr/local/lib/python3.7/dist-packages/yamspy/init.py", line 869, in enter
self.is_serial_open = not self.connect(trials=self.ser_trials)
File "/usr/local/lib/python3.7/dist-packages/yamspy/init.py", line 903, in connect
self.basic_info()
File "/usr/local/lib/python3.7/dist-packages/yamspy/init.py", line 938, in basic_info
dataHandler = self.receive_msg()
File "/usr/local/lib/python3.7/dist-packages/yamspy/init.py", line 1089, in receive_msg
data = received_bytes[di]
IndexError: index out of range
It would be interesting to add type hints (for readability) and test whether mypyc will speed up things.
#!!!
import time
from yamspy import MSPy
CMDS = {
'roll': 1500,
'pitch': 1500,
'throttle': 900,
'yaw': 1500,
'aux1': 1000,
'aux2': 1000
#'aux3': 1000,
#'aux4': 1000
}
#CMDS = [1500,1500,900,1500,1000,1000]
CMDS_ORDER = ['roll', 'pitch', 'throttle', 'yaw', 'aux1', 'aux2']
serial_port = "/dev/ttyUSB0"
with MSPy(device=serial_port, loglevel='WARNING', baudrate=115200) as board:
command_list = ['MSP_API_VERSION', 'MSP_FC_VARIANT', 'MSP_FC_VERSION', 'MSP_BUILD_INFO',
'MSP_BOARD_INFO', 'MSP_UID', 'MSP_ACC_TRIM', 'MSP_NAME', 'MSP_STATUS',
'MSP_STATUS_EX','MSP_BATTERY_CONFIG', 'MSP_BATTERY_STATE', 'MSP_BOXNAMES']
for msg in command_list:
if board.send_RAW_msg(MSPy.MSPCodes[msg], data=[]):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
try:
print('Arming')
CMDS_RC = [CMDS[ki] for ki in CMDS_ORDER]
#board.fast_msp_rc_cmd(CMDS_RC)
while True:
CMDS['aux1'] = 1800
CMDS['throttle'] = 1000
CMDS_RC = [CMDS[ki] for ki in CMDS_ORDER]
if board.send_RAW_RC(CMDS_RC):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
#board.fast_msp_rc_cmd(CMDS_RC)
CMDS['throttle'] = 1050
CMDS_RC = [CMDS[ki] for ki in CMDS_ORDER]
board.fast_msp_rc_cmd(CMDS_RC)
except KeyboardInterrupt:
print('Disarming')
CMDS['aux1'] = 900
CMDS_RC = [CMDS[ki] for ki in CMDS_ORDER]
if board.send_RAW_RC(CMDS_RC):
dataHandler = board.receive_msg()
board.process_recv_data(dataHandler)
#board.fast_msp_rc_cmd(CMDS_RC)
My FC (an old Naze32) flashes green, indicating it's armed, but the motors won't spin. This isn't a problem for either the joystick_async.py or simpleUI.py code; both of those can arm and spin the motors. What needs to be done to arm the motors? I can't seem to find any obvious discrepancies between the example and my code.
Hi,
I wanted to ask regarding the communication with INAV and raspberry pi (3b) model.
I've downloaded the library and connected the wired accordingly, verified that FC TX is connected to Rpi RX and vice versa.
However, I don't see a communication, the "curses ?UX" is not loaded.
I think it's a problem with how I configured the FC via INAV configurator.
Attached two snapshots. Could you please help here?
Thanks
Dancho
I have succefully started simpleUI.py on my SpeedyBee f405 FC via USB cable. My question, is it possible to start manual flight using RC controller and then switch for autonomus controlling with Rasberry PI + YASMPy during flight?
Hello,
Has anybody successfully connected to a FC with a raspberry pi over the onboard Pins? I have deactivated bluetooth and changed many settings but still it doesn't connect successfull, it always times out. If I try another UART where I know it should not work it instantly throws an error...
Via USB everything works great, but usb is not safe enough to fly...
When I'm running commands like MSP_BOARD_INFO
it takes good 5-10 seconds to process each command. Is that normal?
What is the proper way to get fast accel/gyro values from FC? Say 100 times per second.
I've used the library with a betaflight drone and tried simpleui.py, it worked great via raspberry pi.
The issue is that the drone is in "Angle mode" where as I understood it suppose to stabilize itself but it doesn't happen? is there something in the init.py that disables the accelerometer?
In betaflight configurator I see that the acclerometer works?
One more thing, is there an ability to control the barometer?
Best,
John
The analog sticks generate values from 0 to 255 (at least this is what I can get using evdev) , they are normalized (0 to 1) and multiplied by 1000. It's much easier to control the drone if a smaller gain is used instead of 1000 and, ideally, this should be easy to set through command line instead of hard coding it...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.