Ubuntu 20 + Python3 setup


#7

Hey mate,

Glad this has helped you. As you mention, I did do some changes to the scripts, since as you pointed out earlier, the Exceptions module doesn’t exists in python3. I think I would need a little more detail from what you are doing and what errors you are experiencing to help you debug, but it would probably useful to share my connection_template.py and launch_sitl.sh scripts, so I’ll paste them as comments below this.

Hope they are helpful.


#8

The following is the content for the launch_sitl.sh file. I have it located in /usr/local/bin/launch_sitl.sh, and it’s called in the following way to test the connection_template: ~/courseRoot/dk$ launch_stil.sh connection_template.py

File contents:

#!/bin/bash
# Config
SITL_BIN=/home/$user/courseRoot/apm/ardupilot/build/sitl/bin/arducopter
QGC_BIN=/usr/local/bin/qgc.AppImage
DEFAULT_ENDPOINT="tcp:127.0.0.1:5760"
QGC_ENDPOINT="127.0.0.1:14550"
DK_ENDPOINT="127.0.0.1:5762"
# Script Arguments
if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
    exit 2
fi
SCRIPT=$1

function finish {
        kill -9 $(ps -efa | grep qgc | awk -F ' ' '{print $2}') > /dev/null 2>&1
        kill -9 $(ps -efa | grep ardu | awk -F ' ' '{print $2}') > /dev/null 2>&1
        kill -9 $(ps -efa | grep mav | awk -F ' ' '{print $2}') > /dev/null 2>&1
        kill -9 $(ps -efa | grep apm | awk -F ' ' '{print $2}') > /dev/null 2>&1
}

# Launch the sitl binary as a dettached process
# Home: latitude, longitude, altitude (meters above sea level), yaw (pointing south)
echo "Launching SITL instance..."
$SITL_BIN -S -I0 --home 44.501293,-88.062176,177,180 --model "+" --speedup 1 --defaults $apm/ardupilot/Tools/autotest/default_params/copter.parm &
SITL_PID=$!
sleep 5
echo "done!"

# Launch the QGroundControl software as dettached, and send stderr to /dev/null
echo "Launching QGroundControl..."
$QGC_BIN 2>/dev/null &
QGC_PID=$!
sleep 5
echo "done!"

# Start MAVProxy
echo "Launching MAVProxy..."
screen -dm mavproxy.py --master=$DEFAULT_ENDPOINT --out=$QGC_ENDPOINT --out=$DK_ENDPOINT
MP_PID=$!
sleep 5
echo "done!"

#Launch the DroneKit script
echo "Launching DroneKit script..."
python $SCRIPT --connect $DK_ENDPOINT
echo "done!"

#Clean up
echo "Cleaning up..."
trap finish EXIT
echo "done!"

#9

Finally, the following is my connection_template.py file. You can use it as the base for all your other scripts in this course by just adding the relevant logic in the indicated part inside the main() function. However, I suggest you read it and really try to understand it, or even write your own template file from it (for learning purposes).

When calling launch_sitl.sh, it should be done from the ~/courseRoot/dk folder and always inside the virtualenv that contains the correct pymavlink version.

File contents:

from dronekit import connect, VehicleMode, LocationGlobalRelative, APIException
import time
import socket
#import exceptions
import math
import argparse

def connectMyCopter(conn_str):
    if not conn_str:
        import dronekit_sitl
        sitl = dronekit_sitl.start_default()
        conn_str = sitl.connection_string()
    vehicle = connect(conn_str, wait_ready=True)

    return vehicle


def get_arguments():
    parser = argparse.ArgumentParser(description='commands')
    parser.add_argument('--connect')
    args = parser.parse_args()

    return args


def prepare_vehicle_for_flight(vehicle):
    print('Waiting for SITL vehicle to finish initialising...')
    time.sleep(5)

    while not vehicle.is_armable:
        print('Waiting for the vehicle to become armable')
        time.sleep(1)
    print('Vehicle is now armable')

    # Set the vehicle to guided mode
    print('Vehicle is in %s mode'%vehicle.mode)
    #vehicle.mode = VehicleMode("GUIDED")
    vehicle.mode = 'GUIDED'
    while vehicle.mode != 'GUIDED':
        print('Vehicle is in %s mode'%vehicle.mode)
        print('Last heartbeat:%s'%vehicle.last_heartbeat)
        print('Status: %s'%vehicle.system_status)
        print('Waiting for the vehicle to enter GUIDED flight mode')
        time.sleep(1)
    print('Vehicle is now in guided mode')

    #Arm the drone
    vehicle.armed = True
    while not vehicle.armed:
        print('Waiting for the vehicle to become armed')
        print('Last heartbeat:%s'%vehicle.last_heartbeat)
        print('Status: %s'%vehicle.system_status)
        print('Armed: %s'%vehicle.armed)
        time.sleep(1)
    print('Virtual propellers are now spinning!')


def set_and_get_params(vehicle):
    gps_type = vehicle.parameters['GPS_TYPE']
    print('GPS type: %s'%gps_type)
    vehicle.parameters['GPS_TYPE'] = 3
    gps_type = vehicle.parameters['GPS_TYPE']
    print('GPS type: %s'%gps_type)


def arm_and_take_off(vehicle, targetHeight):
    prepare_vehicle_for_flight(vehicle)
    vehicle.simple_takeoff(targetHeight)
    print('Taking off...')

    while vehicle.location.global_relative_frame.alt < 0.95*targetHeight:
        print('Current altitude: %d'%vehicle.location.global_relative_frame.alt)
        time.sleep(1)
    print('Target altitude reached!')


def main():
    args = get_arguments()
    vehicle = connectMyCopter(args.connect)
    arm_and_take_off(vehicle, 10)
    
    # Script logic goes here. Preferably a function call.



    vehicle.close()



if __name__ == '__main__':
    main()

#10

That helped a lot and I was able to get through the course. Thanks!


#11

Glad to read that!


#12

I can confirm this install worked for me and could run the dk scripts. However, there seems to be some steps missing for anyone wanting to follow this exactly, eg, I use the ‘source’ command after changes to .bashrc, need to mkdir ‘courseRoot’, need to include the dk install.

Also, I could not get sim_vehicle.py going and I thought it was installed with the ardupilot install. So there must be another step I am missing.


Still no python3 course update? or a VM?
dronekit.TimeoutError: wait_ready experienced a timeout after 30 seconds
#13

You are right, these instructions are not the full setup, but rather the minimum changes required to the course instructions to work with python3. All other steps from the course are required, such as creating the directories, activating the virtualenv before calling the scripts, etc.


#14

Good stuff, @dash!!!

The main reason the curriculum is using python2 instead of python3 is to strive for software version consistency throughout all of the courses. We use ROS1 pretty heavily in the “Precision Landing and Drone Delivery” course, which can be a PITA to get working with python3.

In our next software version update, we will be aiming to get everything on python3.

Awesome stuff and love your guide for those wanting a jump on python3!


#15

Thanks, Caleb!

Presumably, you are using ROS1 in the last course to work the clamp? I have yet to finish the second course (but getting close), but by the time I get to the last one, I’ll give it a go to either use ROS2, or get ROS1 working with python3.


#16

That is correct @dash! Keep us updated on your ROS2 python3 efforts, that would be epic.


#17

Super helpful, thank you so much!


#18

By the way, when you install dronekit, do you use

sudo pip3 install dronekit

?

Thanks!


#19

Hi Dash,

I tried to do the following for my connection template.py:

#####dependencies#####

from dronekit import connect, VehicleMode, LocationGlobalRelative, APIException
import time
import socket
#import exceptions
import math
import argparse

######functions######

def connectMyCopter():

parser = argparse.ArgumentParser(description=‘commands’)
parser.add_argument(’–connect’)
args = parser.parse_args()

connection_string = args.connect

if not connection_string:
import dronekit_sitl
sitl = dronekit_sitl.start_default()
connection_string = sitl.connection_string()

vehicle = connect(connection_string, wait_ready=True)

return vehicle

vehicle = connectMyCopter()

The script runs without error. However, in the terminal that i run the python script I didnt get the same vehicle returned like the video show (>>APM:copter v xxx >>frame : QUAD). Instead, all i got is this one (which i assume shows that the SITL has started)

abagaskara3@abagaskara3-IdeaPad-3-14ARE05:~/courseRoot/dk$ python connection_template.py
Starting copter simulator (SITL)
Downloading SITL from http://dronekit-assets.s3.amazonaws.com/sitl/copter/sitl-linux-copter-3.3.tar.gz
Download Complete.
Payload Extracted.
Ready to boot.
CRITICAL:autopilot:APM:Copter V3.3 (d6053245)
CRITICAL:autopilot:Frame: QUAD
CRITICAL:autopilot:Calibrating barometer
CRITICAL:autopilot:Initialising APM…
CRITICAL:autopilot:barometer calibration complete
CRITICAL:autopilot:GROUND START
abagaskara3@abagaskara3-IdeaPad-3-14ARE05:~/courseRoot/dk$

If i run the SITL drone separately and specify the IP address in the arguments, this is what i got :

are you experiencing the same issue as well? or is this to be expected when you’re using python 3? thanks in advance


#20

I do however got the following message in the same terminal i launched the simvehicle.py (which shows up everytime i launch the python script)


#21

I just would like to thank you dash for sharing your experience here. Thanks to your information, I just went through the DPP course successfully! Mine was as follows.

$ pip freeze | grep -i mav
MAVProxy==1.8.40
pymavlink==2.4.15

$ pip freeze | grep -i drone
dronekit==2.9.2
dronekit-sitl==3.3.0

As you suggested, what I did was to downgrade pymavlink==2.4.15–>>pymavlink==2.4.8 in the virtual environment and hand over vehicle object to some functions. Since I use a very old laptop (EPSON Endeavor) in which Ubuntu 20.04.2 LTS was already installed, your information helped me a lot!


#22

I tried this with 21.04 but no luck. Got stuck installing prior version of pymavlink.


#23

You are welcome, glad to be of help!


#24

Hey sorry for the late reply. Did you figure it out? Is it still relevant for you?


#25

NBD. 20.04 worked, tried 21.04 just for kicks.


#26

Hi, thank you so much for your help!

I have however been experiencing the following timeout error and have no idea why…

Starting copter simulator (SITL)
SITL already Downloaded and Extracted.
Ready to boot.

Connecting to vehicle on: tcp:127.0.0.1:5760
WARNING:dronekit:Link timeout, no heartbeat in last 5 seconds
ERROR:dronekit.mavlink:Exception in MAVLink input loop
Traceback (most recent call last):
File “/usr/local/lib/python3.8/dist-packages/dronekit/mavlink.py”, line 211, in mavlink_thread_in
fn(self)
File “/usr/local/lib/python3.8/dist-packages/dronekit/init.py”, line 1370, in listener
raise APIException(‘No heartbeat in %s seconds, aborting.’ %
dronekit.APIException: No heartbeat in 30 seconds, aborting.
Traceback (most recent call last):
File “vehicle_state.py”, line 38, in
vehicle = connect(connection_string, wait_ready=True)
File “/usr/local/lib/python3.8/dist-packages/dronekit/init.py”, line 3166, in connect
vehicle.initialize(rate=rate, heartbeat_timeout=heartbeat_timeout)
File “/usr/local/lib/python3.8/dist-packages/dronekit/init.py”, line 2275, in initialize
raise APIException(‘Timeout in initializing connection.’)
dronekit.APIException: Timeout in initializing connection

Any advice would be appreciated


launchSitl "can't find '__main__' in module in ' ' error