Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Onboard Computer Setup
Description: This tutorial shows how to setup the onboard computer on AscTec MAVs that is connected to the HighLevel Processor.Keywords: asctec, pelican, firefly, atomboard, mastermind, onboard computer, quadcopter, hexacopter,
Tutorial Level: BEGINNER
Contents
Overview
This tutorial shows how to setup the onboard computer (like AscTec Atomboard or MasterMind) on AscTec MAVs that is connected to the HighLevel Processor. We assume that there is Ubuntu 12.04 (Server) installed on the onboard computer. Furthermore, there should be a WiFi network where the computer can connect to.
Connecting the Onboard Computer with the Highlevel Processor
Connect one of the two serial ports of the Atomboard (/dev/ttyUSB0-1) or one of the four serial ports of the MasterMind (/dev/ttyS0-3) to the serial port 0 of the HLP. It is important o use the cable with a "loop" on the HLP side, which connects the CTS pin (pin 3, next to the RX/TX lines) permanently to GND (pin 6).
General Setup
WiFi
We configure the computer such that it connects automatically to a WiFi network during startup.
WPA Supplicant
We use wpa_supplicant for managing the WiFi connection. If it is not installed already:
sudo apt-get install wpasupplicant
Then, uninstall any networmanagers like NetworkManager or WICD:
sudo apt-get remove networkmanager wicd
For a WPA(2) secured WLAN, do the following: Run
wpa_passphrase my_awesome_ssid # with this call, you can type the password to stdin
This will create something like this:
network={ ssid="my_awesome_ssid" psk=hashed_version_of_your_password }
Copy this to a file (or create it), e.g. /etc/wpa_supplicant/wpa_supplicant.conf. More of those entries are possible, e.g. for different WLANs. However, wpa_supplicant's choice seems to be quite arbitrary if there are multiple WLANs available.
Then, edit /etc/network/interfaces.The section for wlan0 should look like this:
auto wlan0 iface wlan0 inet dhcp wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf post-up /sbin/iwconfig wlan0 power off # makes sure power management is off --> short ping times
A very good wpa_supplicant tutorial can be found here (in German) or here
Avoiding High Latencies on the WiFi Interface
The wifi driver decided to switch power managenemt on in the more recent Ubuntu versions, resulting in high latencies for inbound connections. To avoid this, power management gets permanently switched off by the last line in /etc/network/interfaces in the previous section
The state of power management can also be checked by:
iwconfig wlan0 |grep "Power Management"
or temporarily switched on/off by:
sudo iwconfig wlan0 power off
User Access to serial Ports
As of Ubuntu 12.04, you need to add the user you are working with to the dialout group in order to access the serial ports without root permissions:
sudo adduser <username> dialout
Grub
Add the following to /etc/default/grub to the GRUB_CMDLINE_LINUX_DEFAULT parameter. This removes some i8042 related error messages during boot (also speeds up boot):
GRUB_CMDLINE_LINUX_DEFAULT="i8042.noaux=1"
Then update Grub:
sudo update-grub
MasterMind Specific Setup
This section describes a few modifications that might be necessary when working with the AscTec MasterMind
Network
We uninstalled networkmanagers above, but we might want that the wired network interface eth0 will be brought up/down automatically and have an IP adress assigned whenever the network cable gets connected/disconnected:
Install ifplugd:
sudo apt-get install ifplugd
Comment out auto eth0 in /etc/network/interfaces.
add "eth0" to INTERFACES in /etc/default/ifplugd.
- restart
If you want some automatism, e.g. put down the wifi when a cable is connected (to avoid conflicts), this might be interesting.
Under the Ubuntu server version, the boot process took minutes waiting for a conection on eth0 when the cable was disconnected (the usual case). This should be avoided by configuring ifplugd as describe above. Otherwise, comment out sleep 40 and sleep 59 in /etc/init/failsafe.conf. A full description can be found here
Using the Serial Ports for Fast Communication
This applies only if you are using the hardware-serial ports (/dev/ttyS0 - /dev/ttyS3) on the MasterMind. You can skip these steps if you connect via a USB to serial adapter.
If you do not plan to use baudrates higher than 115200 Baud, don't transmit packets at high rates and you do not use ethzasl_sensor_fusion, you can safely ignore the following. If any of the above answers is yes, there are two issues with the serial ports:
- By default, the clock of the serial chip is configured such that it does not allow baudrates higher than 115200
- The size of the receive buffer of the serial chip is just 16 bytes. By default, an interrupt is triggered when 8 bytes are in the buffer. This threshold is too high for high packet rates and a loaded system, i.e. the buffer is not read fast enough until it is full.
Update: with newer Kernels (e.g. in Ubuntu 14.04), it seems like the RX-buffer behaviour is not a problem anymore. Thus, you may try getting away by solely adjusting the maximum baudrate as shown below. Note the different "real" baudrate in this case, as explained below.
Adjusting the Maximum Baudrate
Fixing the first issue can be done by some funny hex commands executed by Grub during startup. Download this file 09_config_serial.
sudo cp 09_config_serial /etc/grub.d sudo chmod +x /etc/grub.d/09_config_serial # make it executable sudo update-grub # rebuild grub config
Make sure the changes were applied by looking into /boot/grub/grub.cfg, where the content of the above file should be visible.
This configures the clock of the serial chip to 14.769 MHz, allowing higher baudrates of up to 921600 Baud.
Unfortunately, the serial8250 driver doesn't recognize this clock change, so that the effctive baudrate will now be 8x the set baudrate, i.e. setting 115200 will result in 921600 Baud. However, we'll fix that in the next section.
Changing the RX Buffer Behaviour
To resolve the second issue, we need to lower the RX Buffer level at which the receive interrupt get triggered. In practice, a level of 4 bytes turend out to work well. This unfortunately requires recompiling the kernel. Since we are making changes in the serial driver already, we can also fix the baudrate scaling issue from above.
- Download and install build tools:
apt-get install initramfs-tools fakeroot module-init-tools libncurses5 libncurses5-dev kernel-package build-essential
- Get the kernel sources:
apt-get source linux-image-`uname -r`
Either download one of these patches serial_fifo_irq_4_kernel_3.2.patchserial_fifo_irq_4_kernel_2.6.patch according to your kernel version into the linux-* directory just created by apt-get source, cd into that directory and apply the patch:
patch -p1 < serial_fifo_irq_4_kernel_3.2.patch
Or: Since it is hard keeping up with, and supporting all kernel versions, here is what needs to be changed, in case the patches form above don't fit your kernel version: search serial/8250.c (used to be here: linux-3.X.0/drivers/tty/serial/8250.c), in that file, 2 changes are required. submitting patches is highly appreciated.
- Replace
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
- by
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01,
- This sets the buffer interrupt level correct.
- Look for
baud = uart_get_baud_rate(port, termios, old,
- and insert
port->uartclk = 14745600; //set fixed uartclk for 16550
before that line
- Replace
- Generate kernel config with only the necessary modules:
make localmodconfig # if you do that one, it has to be on the MasterMind! make menuconfig # optional if you want to configure other modules etc.
- (optional) to build on multiple cores:
export CONCURRENCY_LEVEL=j # j=number of cores + 1
Compile the kernel and create debian files. append-to-version can be an arbitrary string:
fakeroot make-kpkg --initrd --append-to-version=-serialport_mod --revision 1 kernel-image kernel-headers
- Get a coffee or two ...
- Install the kernel image and the headers:
sudo dpkg -i ../linux*
Reboot, then check with uname -r if your newly compiled kernel got booted. If not, you need to edit DEFAULT in /etc/default/grub, followed by sudo update-grub. More information about configuring the default kernel to be booted (especially with the new submenus) here: Grub2/Submenus
The patch from above resolves the baudrate scaling issue after reconfiguring the serial port clock only for this newly compiled kernel. If you boot a default kernel, remember that the baudrate will be again 8x the one you have set.