Monthly Archives: March 2016

Node properties

One of the nice things about silkopter is that is very easy to add new types of nodes to the system.

A node can be anything from a sensor to a low pass filter to a PWM generator like PIGPIO. All nodes have the following properties:

  • Zero or more input streams. Each stream has a type and a rate
  • Zero or more output streams. Same as the inputs, they have a type and rate
  • An Init_Params struct that decides the initialization params of the node. Once the node is created this cannot be changed. The usual params that go in this struct is the rate (process frequency), number of channels for a PWM sink etc.
  • A Config struct that holds changable configuration. This can be changed at any time and contains PID settings for example

The Init_Params and the Config structs are custom, per node. They have to be serializable to json for loading/saving, serializable to binary for comms (the json serialization can be used here) and they need to be editable in an UI for the Ground Station

Silkopter defines the Init_Params and Comms in a json file – one per node – and then generates the actual C++ structs and serialization code from this json description. The UI for editing is dynamic, based on the serialized json of the structs.

So for example the load flow is this:

  • the settings.json file is loaded and converted to a json structure using the rapidjson library
  • the list of nodes is iterated and nodes are created from it
  • each node has its init method called with the init_params json passed to it
  • the init method deserializes the init_params json using generated code into a Init_Params C++ struct

The save flow is the inverse of the one above.

Sending the node Init_Params and the Config to the GS and editing it:

  • The get_init_params (or get_config) is called for a node. This serializes the internal Init_Params or Config to json using the generated code
  • The json stringified using rapidjson and sent to the GS
  • The GS parses the string using rapidjson back into a json data structure
  • A QT item model is used over this json to populate a tree view with the data
  • When data is changed by QT as a response to user interaction (typing a new value for example) the json changes. As a result of this its serialized back to string, sent to the Brain which then calls set_config with the json.

So in order to add a new node, 3 steps have to be done – all of them in the brain. The GS is unchanged:

  1. Create the node C++ class with all the processing needed
  2. Create a json description of the Init_Params and Config and generate the code for them using autojsoncxx library
[
    {
        "definition" : true,
        "namespace" : "sz::ADC_Ammeter",
        "name": "Init_Params",
        "members":
        [
            ["uint32_t", "rate", {"required": true, "json_key" : "Rate (Hz)", "default" : 0}]
        ]
    },
    {
        "definition" : true,
        "namespace" : "sz::ADC_Ammeter",
        "name": "Config",
        "members":
        [
            ["float", "scale", {"required": false, "json_key" : "Scale", "default" : 1}],
            ["float", "bias", {"required": false, "json_key" : "Bias", "default" : 0}]
        ]
    }
]

3. Register the new node in the UAV node factory:

m_node_factory.add<ADC_Ammeter>("ADC Ammeter", *this);

 

The big advantage of having the serialization code generated is that it’s impossible to make mistakes.

The nice thing about having the UI generated is that the GS doesn’t have to change every time a new node is added or a new property is added/removed from an existing node config or init params.

 

So in the new GS I intend to keep this but I really want to get rid of the json definition file and replace it with a domain specific language. Main reason is that the json is not as expressive as I want and doesn’t support all the attributes I need – like ranges for the values.

I already started working on a flex/bison grammar for this and a library that will handle the reflection.

More details and a working example soon.

Advertisements

New GS

In the past week I started working on the new Ground Station. The problems I’m trying to fix are:

  1. I want a dedicated GS, not a laptop. For this purpose I’m trying a raspberry pi with a 7 inch display (the official RPI touchscreen display), together with a custom case, 2 RC sticks and various buttons. The reason is that a laptop is unwieldy, not bright enough in direct sunlight, tends to get busy with other tasks in the worst moments, doesn’t have a touchscreen (at least my current laptop doesn’t)
  2. I want a nicer interface that focuses on the main purpose of the GS – flying. The current one focuses more on editing the nodes of the quad.

So I started a new project, the GS2 using QT’s QML and a touch driven UI. So far so good, here are some screenshots:

 

The resolution is 800×480, a bit small TBH but enough for now. The display size is 7″.

So far the experience in QML is great, it takes very little time to build a nice, functional UI. It does require to build proxies for anything that has to be exposed from the C++ side to qml but that’s a good thing as it separates the UI from the logic.

The main things that I still have to figure out are:

  1. How to create a property sheet in QML. This is used to show the init params and configuration for nodes. This UI is generated in the current GS so there is no need to write custom UI for every node but just a description of the parameters in a json file.
  2. How to write the node editor in QML. Screen real-estate is limited and the node structure can get complex. One possible solution is to allow node groups. Basically take the IMU and low pass filters ang build a meta-node – a Filtered IMU – and treat that as a new node in the UI. Or group all the Navio sensors together in a new Navio Node and avoid all the current clutter. This is an interesting feature that deserves a few weekends.

 

The physical part of the GS – the case, sticks, buttons are still to be designed but I’m sure I can come up with something in a few weekends. The main parts will be:

  • A raspberry pi to drive the display and run the actual GS
  • An AVR to read the sticks, battery voltage and buttons. Could be replaced with another multichannel ADC and the RPI GPIO
  • A few analog sticks. I’m thinking to salvage the ones in my TH9x remote or buy a few of these or these
  • A RFM22B and 2 TL-WN722 wifi cards for the comms. This will be in a detachable module in the GS, connected by a usb cable so I can mount it higher or on top of my car.
  • LEDs, piezo speaker etc

I already have the rpi + display and the first version of the GS working, check out the video here:


All in all – a few months of work. I hope I don’t get demotivated.

 

 

Comms, revisited

After the latest incident and the loss of my quad it became clear that I need reliability. So far I focused on physical reliability – if the quad is sturdy enough to take a light crash, if it’s well balanced, etc. But I kind of ignored the other 2 aspects – software and comms. Well – not ignored, more like I hoped for the best.

So the next issues to fix are:

  1. Solid comms for the commands (RC) and telemetry. The RFM22B is the perfect candidate for this:
    1. It’s lightweight and small.
    2. Very sensitive receiver (-104dbm @125Kbps)
    3. Powerful TX amp @20dbm
    4. 64byte FIFO so I can drive it directly from the raspberry pi
    5. SPI interface, which the RPI has enough
    6. Good penetration due to the low frequency (433Mhz)

With this setup I should have 5-10Km range, way more than the WIFI video like allows.
The issue will be the comms protocol as the device is half-duplex and the bandwidth is not that much. I made a quick calculation and it should take around 5ms to send an entire 64byte message. With a simple protocol where the GS is the master and the quad the slave, I can allocate 5ms slots to each in turn. This will give me a symmetric 7Kbyte bandwidth, -protocol losses lets say a 5Kbyte bandwidth per second. Should be enough for control and telemetry data.

2. Solid software, especially the GS. I intend to get a RPI3 and display and build a dedicated GS to replace my laptop. For now I will keep my PS4 controller but in the future I will aim to build an entire RC system with integrated touchscreen around the RPI.

I want to run the RPI without an X server and for this I will need a QT version that supports this. Don’t know if it’s possible though.
If this fails, I’ll stop using QT and do all the rendering and UI using something else but this will be quite painful… I’m used to QT and despite all it’s quirks it’s very powerful when doing quick UI work.

 

What I do know that works in the current setup is:

  1. The RPI2 is powerful enough to handle a quad with WIFI video streaming. It was using ~16-20% CPU at any moment with around 5 threads so no issues here
  2. The case I designed is very sturdy. It’s a combination of 10mm carbon fiber tubes for the arms and ABS plastic for everything else.
  3. Flight time with the current weight of 650grams is around 20-25 min with a 3000mAh multistar LiHV battery. Enough time to enjoy the landscape
  4. The motors + ESC pair are a nice match. RcTimer 1806 1450Kv and RTFQ 4-in-1 12A ESC seem to handle the load nicely. A bit underpowered due to the props – 7×2.4inches but I plan to move to 8×4.5 for the next quad.

 

So back to the drawing board for a while.

 

 

 

 

 

Crash

I took the quad for a spin yesterday and figured out 4 things:

  1. It flew, quite good. Very stable, video quality was good and the signal was very strong even 4-500 meters away
  2. I crashed a few times. See video here: https://www.youtube.com/watch?v=AjwiUQltHaE&feature=youtu.be
  3. Flight time was around 20-25 min with a 3000mAh Multistar LiHV battery. Average amps for hover was around 6-7 which is great. AUW around 630g
  4. Eventually it flew away in a near-by forest and I couldn’t find it. The reason was a sudden loss of signal which triggered the fail safe routine. The quad started climbing to 50m, went home and then dropped to 5m. Problem was that ‘home’ was a few hundred meters into the near-by forest due GPS interference from the camera….

So it’s gone, have to build another one.

The lesson here is that I have some software issues to iron out and that I really need another signal path for the control. I plan to use a rfm22b for this.

The material loss is not that huge – a raspberry pi, 4 rctimer 1806 motors, a brand new battery and a Navio board. A total of 250 euros plus about 2 weeks of work to print all the pieces, etc.

 

So the next one will need to fix these issues:

  1. Rock solid RC link for control
  2. Solid software without glitches. My GS crashed once in mid-flight (see video) due to the h264 decoder
  3. More portable GS. A laptop with 2 wifi cards, a ps4 controller and many wires is not a fun way to go to the field and fly
  4. The raspicam interferes with the GPSsomething fierce. Even after copper shielding the H Acc went from 2m to 50m after starting the camera…