Cover still WIP.
It tool only 3 tries to figure out how to pack everything. It weights 30g without the electronics and 180 with the raspberry pi, crius board, ESC, WIFI and sonar.
There are 4 layers. First the sonar, at the bottom. Then the ESC and the raspberry pi. On top of them there is a plastic bridge holding the WIFI card and on top of it there’s the crius.
At the front there is space left for the camera with its servo.
The motor wires will go below the ESC board – there are around 15mm of clearing there.
So far it looks like the quad will weight around 820g – including the 3s 2200mAh battery. My old quad weighted around 1100g, mostly because of the heavy 450 frame and the gimbal. I calculated that every 40g gives me an additional minute of flight so I should be able to fly for ~20 minutes withe the new setup. And this is without considering the new bigger props – 10×4.5 vs 9×4.5 which should make the motors a bit more efficient at hover speeds.
This morning I started putting the quad together. I need to print the electronics case to fit all these:
1 – Raspberry pi – the brain
2 – Crius AIOP v2 – the io_board with all the sensors
3 – The Quattro ESC flashed with BlHeli with closed loop control
4 – The Alfa 036H wifi card
6 – SR04 Sonar
and the rpi camera of course.
The voltage/current sensor is missing from the picture.
Packing them in a small encosure while also keeping weight low will be tricky..
Here’s a few pics with the quad as well. It has 10 inch props and Suppo 2208 motors. The arms are 10mm carbon fiber booms. The motor mounts are printed on my prusa I3 and they also act as legs.
The whole frame weights 130g and is 54cm diagonal motor to motor. This is less than half the weight of my old F450 frame while being way stiffer.
I finally have the ground station (gs) talking to the brain (raspberry pi) and the io_board (crius/avr). I get sensor data, can calibrate the accelerometer/gyro/compass, send uav and camera input and so on.
The io_board sends sensor data at 500Hz to the brain and also runs a rate PID at 250Hz. Motors are mixed on the io_board using a throttle input from the brain.
The brain will do AHRS at 500Hz using the sensor data from the io_board and it forwards data to the gs at 30Hz.
The next step is to get the io_board simulation working again to be able to test the rate pid, stability pid, motor mixer and GS.
I managed to get the rpi and crius boards to talk over the serial port at 500000 baud.
All I had to do is add init_uart_clock=16000000 in /boot/config.txt on the rpi and that’s it – I can send data over. Now the problem is getting data across reliably. This proved more problematic and I ended up spending 3 days on it.
I’m using a simple wrapper class that packs arbitrary messages and passes them through a socket. The packet structure used to be this:
[msg] -> uint8_t
[payload size] -> uint8_t
[crc] -> uint16_t. This is the crc of the whole package, including the msg and the size
This allowed me to detect corrputed packages and ignore them.
The packets are processed like this:
- read the first byte if data – this is assumed to be the message
- read the size
- read the crc
- zero out the crc byted in the data stream
- compute the crc for the data stream up to [size] bytes
- if crc is ok – we have a message
- if the crc is wrong, pop the first byte and reiterate
It’s done like this because I avoid using message markers to save bandwidth – so I have to assume that any byte can be the beginning of a message.
Problem is that when a 200 byte message is corrupted the code skips each byte and treats the rest as a potential new message and so on, until all the 200 bytes are exhausted. This takes too long.
Second problem is that in order to detect a corrupted message, I need the whole message to compute its crc. This is an issue as the corrupted byte might be its size – which will result in waiting for bytes that might never come (or come very slowly).
To fix these I changed the message structure to this:
[magic] – 0x3F – early out for corrupted messages
[msg] – uint8_t
[size] – uint8_t
[header crc] – uint8_t – this is the crc for the header only so a crc8 is sufficient. Also quick to compute.
[payload crc] – uint16_t
The header crc allows me to detect and discard very quickly corrupted messages – only 4 bytes are needed to discard any message of any size.
This added 2 bytes of overhead though but for now it’s ok.