5 Oct 2013

Interactie Checklists



Every now and then a new blog post or forum thread pops up something along the lines of "Be careful, I got cut by the propeller ..." with ugly images attached.

UAVs are complex solutions and can be dangerous. The technology itself can help prevent accidents but eventually in most cases it boils down to human errors. I have fond memories sitting in a cockpit while going through checklists. We should learn from the real aviation and adopt checklists to make flying UAVs safer. I am always going through my checklist on paper before a flight. This is a proven approach to keep risks low. In our situation we could take the idea of paper checklists even one step further: interactive checklists. It would be even nicer if the groundstation software would aid the operator going through the checks. The GCS could help by displaying relevant values which need to be checked and allow user input where needed in a structured ways, step by step.

The Image above shows a mockup of a tablet base UI which could be used as checklist in the field. If such a feature would be implemented in DroidPlanner or Andropilot it could also offer GUI components to switch mode or read settings while going through the checks. Below is my checklist for an electric plane. It might look different depending on vehicle (even for fixed wing planes). I think it would be important to make such checklists configurable. The user should be able to re-order and add/remove items.

From preparation to launch, during the mission and while landing different checklists are required. The checklists could be organized in tabs.

My checklists:

Preflight check
[  ] Check payload battery
[  ] Check payload on
[  ] Check UAV battery
[  ] Check airspeed sensor clear
[  ] Turn on transmitter
     [  ] Mode manual
     [  ] Power idle
[  ] check prop clear
[  ] Power up UAV
     [  ] block airspeed sensor
     [  ] don't move UAV until elevator flicks 3 times
[  ] Connect telemetry
[  ] Check 3D GPS fix
[  ] Check altitude
[  ] Check airspeed
[  ] Check Home Location
[  ] Check cruise speed
[  ] Set home altitude to realtive alt.
[  ] Check moving surfaces [Manual]
[  ] Check moving surfaces [Stabilize]
 
Mission planning
[  ] Wind direction and speed?
[  ] Auto take off? Angle ___, Altitude ___
[  ] Check default altitude ___
[  ] Check altitude graph
[  ] Check distance
[  ] Upload mission
[  ] Download mission again and check
Take off
[  ] Check prop thrust?
[  ] Wind direction and speed
[  ] Takeoff flight path clear of obstacles?
[  ] Mode auto
[  ] Check elevator (auto takeoff only)
     launch against wind
Landing
[  ] Check home altitude
[  ] Check cruise speed
[  ] Check wind direction and speed
Shutdown
[  ] Power idle
[  ] Mode manual
[  ] Disconnect Telemetry
[  ] Power off


3 Oct 2013

APM - simple long range wireless telemetry










This is a short howto on building a simple wireless groundstation for 10-20 km UAV telemetry. For simplicity reasons the groundstation has no tracking capabilities. The user’s input device can be a laptop or a tablet/smartphone (android for now).


The input device connects via bluetooth (SPP) to the groundstation and the signal is relayed from there via RFD 900 telemetry modem (3DR modem does work as well). The RFD 900 modem has a built in diversity antenna system. It can use 2 different antennas. In my case an omni-directional rubber duck antenna for short range and a direction patch antenna for long range. The patch antenna must be pointed roughly into the direction of the UAV (45° angle).


I have used a teensy 3.0 board to do the message buffering/passing between the bluethooth modem, a USB port and the RFD900. The teensy costs roughly usd 20, has 3 hardware UARTs and packs a fair amount of power (Cortex M4 up to 96MHz).


Internals
tripod

Bill of Materials





Configure Bluetooth Modem

The BlueSmirf Gold uses the RN-41 AT command set. By default, the modem should be set to 57.6 kilo baud. This is the default speed for wireless telemetry also, this means it should work aut of the box if wired correctly to the teensy (or directly to the RFD 900 modem). More information on wiring a BlueSmirf to an FTDI cable can be found here.


Wiring

This illustration describes the wiring between teensy 3.0, BlueSmirf Gold and RFD-900.


Blue: Teensy TX <-> Modem RX
Yellow: Teensy RX <-> Modem RX


Teensy 3.0 Pins

Code

The programm that is running on the teensy can do 2 things:
  • just play relay between serial links (passthrough). This is low latency but does not allow modifying packages.
  • buffered. In this mode the serial link will buffer until it receives a full mavlink message. Before sending it to the target, it can be modified or dropped (or routed/duplicated to another serial port).
The code relies on the AP_HAL and a modified GCS_Mavlink library (without FastSerial, we have hardware UARTs and mavlink 0.9 removed).

ArduMavProxy.ino

#include <GCS_MAVlink.h> #include "ArduMavProxy.h"

// #define DBG


// message structs


static mavlink_message_t msg1;

static mavlink_message_t msg2;
static mavlink_message_t msg3;
static mavlink_status_t status1;
static mavlink_status_t status2;
static mavlink_status_t status3;

// Serial devices
static comm_t s_src     = {"", 0, &Serial1, msg1, status1, 0, 1};
static comm_t s_modem   = {"", 0, &Serial2, msg2, status2, 0, 2};
static comm_t s_ext = {"", 0, &Serial,  msg3, status3, 0, 3};

void setup() {
Serial.begin(TELEMETRY_SPEED);
Serial1.begin(TELEMETRY_SPEED);
Serial2.begin(TELEMETRY_SPEED); // FIXME: s_modem.serial->begin() doesn't work
//Serial3.begin(TELEMETRY_SPEED);

// set pins to default state
pinMode(PIN_ARM, OUTPUT);
pinMode(PIN_AUTO, OUTPUT);
digitalWrite(PIN_ARM, LOW);
digitalWrite(PIN_AUTO, LOW);
}
void loop() {

// No passthrough to modem so we queue src packages
uint8_t ret1 = read_packet(&s_src, &s_modem, false);

// TODO: check for comm_t.has_packet
if (ret1) { // we got a complete message from the source
route_packet(&s_src, &s_modem);
flush_packet(&s_src);

#ifdef DBG
Serial.print("Sats: ");
Serial.print(gps_satellites_visible);
Serial.print(", fix: ");
Serial.print(gps_fix_type);
Serial.print("\t");
Serial.print(motor_armed, HEX);
Serial.print("\t");
Serial.println(base_mode, BIN);
#endif

digitalWrite(PIN_ARM, (motor_armed) ? HIGH : LOW);
digitalWrite(PIN_AUTO, (mode_auto) ? HIGH : LOW);
}

// read mavlink package from modem
uint8_t ret2 = read_packet(&s_modem, &s_src, true);
if (ret2) { // we got a complete message from the source
// TODO: implement fast passthrough for 2 channels
route_packet(&s_modem, &s_ext);
flush_packet(&s_modem);
}

#ifndef DBG
// No passthrough to modem so we queue src packages
uint8_t ret3 = read_packet(&s_ext, &s_modem, false);
if (ret2) { // we got a complete message from the source
route_packet(&s_ext, &s_modem);
flush_packet(&s_ext);
}
#endif
}


ArduMavProxy.h
// Get the common arduino functions
#if defined(ARDUINO) && ARDUINO >= 100
#include
"Arduino.h"
#else
#include
"wiring.h"
#endif

#define TELEMETRY_SPEED  57600  
// How fast our MAVLink telemetry is coming to Serial
#define PIN_ARM 13
#define PIN_AUTO 14
#define MAVLINK_FRAME_LENGTH 263

#include <GCS_MAVlink.h>
#include
"include/mavlink/v1.0/mavlink_types.h"
static uint8_t      base_mode=0;

static bool         motor_armed = 0;
static uint8_t      mode_auto = 0;

typedef struct comm_t {
char buffer[MAVLINK_FRAME_LENGTH + 1];
int buffer_count;
Stream *serial;
mavlink_message_t msg;
mavlink_status_t
status;
bool has_message;
uint8_t chan;
};


util.ino
// utility methods

// bit juggling
boolean getBit(byte Reg, byte whichBit) {
boolean State;
State = Reg & (1 << whichBit);
return State;
}


byte setBit(byte &Reg, byte whichBit, boolean stat) {
if (stat)
Reg = Reg | (1 << whichBit);
else
Reg = Reg & ~(1 << whichBit);
return Reg;
}


/**
* flush input buffer
*
* the user must make sure that the buffered packet was used before flusing.
*/
void flush_packet(comm_t *src) {
src->buffer_count = 0;
src->buffer[0] =
'\0';
}


/**
* write buffer to serial
*
* writes a buffer and decoded incoming mavlink serial packet to another
* serial port.
*/
void route_packet(comm_t *src, comm_t *target) {
for (int i=0; i <= src->buffer_count; i++)
target->serial->
write(src->buffer[i]);
//flush_packet(src);
}


/**
* read a mavlink packet
*
* returns 1 if we got a complete packet. returns 0 if we need to read
* more into the stream.
*
* passthrough is for minimal latency. Best used for sniffing or routing only.
*/
uint8_t read_packet(comm_t *src, comm_t *target, bool passthrough) {

//grabing data
while(src->serial->available() > 0) {

// the packet should have been used, flush it to prevent buffer overflows
if (src->has_message) {
src->has_message =
false;
flush_packet(src);
}

char c = src->serial->read();

// buffer the received character
src->buffer[src->buffer_count] = c;
(src->buffer_count)++;

// buffer overflow protection
if (src->buffer_count == MAVLINK_FRAME_LENGTH) {
// flush stream buffer if full
//src->buffer_count = 0;
//src->buffer[0] = '\0';
flush_packet(src);
}

if (passthrough)
target->serial->
write(c);

// try to grab message, decode if complete
if(mavlink_parse_char(MAVLINK_COMM_0, c, &(src->msg), &(src->status))) {
src->has_message =
true;
return 1;
}
}

return 0;
}

Download

The latest source code is available browseable on Github or as zip download.

Connecting

Windows Mission Planner

Windows Mission Planner can be downloaded at ardupilot.com.


You have to options: connect with USB-A to Micro-USB B cable to teensy or use bluetooth. The following section describes the Bluetooth connectivity setup.


Enable Bluetooth and pair with the ground station.
Add bluetooth adapter from task tray
Your device should show up here


Make sure you get the manual pairing option.
Enter PIN

Device Paired
Verify from devices. Right click the device and select Properties » Services (“SPP” should be displayed).


If done, the comm port shown in the last screenshot can be used from MP to connect (57.6K).


DroidPlanner (Android)

Enable Bluetooth and pair with the ground station.


Open DroidPlanner, select settings and configure the modem to BLUETOOTH.

Andropilot (Android)

Enable Bluetooth and pair with the ground station.


After launching the program, click on the [Bluetooth] overlay button to connect.