Pleco Phase 03: Finally drivable

I wrote about Phase 02 in September 2013 and listed goals for the Phase 03.

Most of the goals are implemented and finally it is a joy to remote drive the car.

I attached a wide angle lens to the existing camera and that made a huge difference. The camera crops a bit from the 180° angle but clearly the wider the better. I also made my first 3D print to better attach the camera to the servos.

Tegra 3 based Ouya was replaced with a Tegra K1 based Jetson TK1. That made it easy to stream a low latency H264 video over the network. Due to USB 2.0 and network limitations, the best quality video stream that can be enabled from the controller application is 800×600 2 Mbps.

The Microsoft Lifecam decreases the FPS in low light conditions so I added some V4L2 controls. The brightness is set to minimum to get the maximum FPS. In addition to that, the controller application now has manual focus and manual zoom.

The latency is low enough to drive over a long distance. In local wired network, the application latency (from the controller application to the slave application and back to the controller application) is 1-2 ms. Over my local WIFI it increases to 4 ms. In the video above the car was connected to an LTE network and the communication was routed over a distance of 800 km (the relay is in Stockholm and I live near Helsinki). The latency was around 60-80 ms and it did not introduce any noticeable delay. A friend of mine even drove the car from Gold Coast (that is in Australia, almost 15000 km away!). The latency was around 450 ms and while the delay was obvious, he was still able to drive it.

I also measured the actual visual delay, i.e. how long it takes for the controller application to show what the camera sees (“photon to display”). I did that by taping a led to the camera and using an external microcontroller with two light sensors. One sensor was taped to the led on the camera and the other one was taped to the monitor showing the controller application. I then measured the difference of the two sensors.

The visual latency was about 105 ms with 1 ms network latency. The camera is supposed to be 30 FPS so that can introduce a maximum of 33 ms of latency and my monitor is 60 Hz, so it can introduce a 16 ms latency. On average something else still introduced a 80 ms latency. That 80 ms may be the sum of getting the video stream from the USB camera to the Jetson, encoding it, sending it, buffering a frame, decoding it and then finally showing it. While it might be possible to get the latency down, it is already low enough for remote driving within a 1000km range :)

The project will never end and there are already some goals for the Phase 04:

  • GPS
  • AHRS based car orientation visualisation
  • 60 FPS (stereo?) camera
  • Control the webcam based on driver’s head orientation
  • Improved gamepad etc. controls

Wireless MCUs and power consumption, part II

In the Part I I described my real project with the radio: a wireless power consumption meter. But it is supposed to be a low power MCU so why not run it indefinitely with a renewable power source?

Solar power is the easiest form of renewable energy and I decided to try it out. That is of course not an option in the dark closet where the smart electricity meter is so I ended up designing a modular solar powered wireless soil moisture sensor.

Measuring the moisture of the soil is only a secondary objective. The real goal is to see if I can keep the radio running continuously throughout the Finnish winter. In December 2013 we had a total of 24 minutes of sunshine during a period of 18 days, so having solar power available should not be taken for granted.

Another issue is the temperature as common batteries must not be charged below zero degrees Celsius. I decided to go with a large solar panel from Sparkfun and 10 F super capacitors from Digikey. The panel provides a maximum of 9.15V which nicely matches four 2.7V super capacitors in series.

The voltage of solar panels decreases quickly if too much power is drawn from them. All larger solar panel systems use maximum power point tracking (MPPT) which tracks the voltage and limits the power draw if the voltage drops. I tried to find MPPT solutions for small systems but did not find anything suitable for this project. Adafruit’s Solar Lithium Ion/Polymer charger is based on MCP73871 but that seems to be designed for batteries alone. There is also bq25570 from TI which looks otherwise very well suited for this kind of project but it seems to be designed for even smaller solar panels.

Solar powered soil moisture sensor
Solar powered wireless soil moisture sensor

The final software will make the measurements once an hour and sleep the rest of the time in the deepest sleep mode. The power consumption in the sleep is only a few micro-amps for the whole thing.

I made some initial tests with a five minute interval behind glass windows and without direct sunshine. During the last day I tried to keep the panel pointed directly to the sun, when possible and that clearly shows in the graph below.

Solar measurements
Solar panel and super capacitor voltages over time.

For now I have just printed out the values and created a graph about the measurements. For the electricity measurements I was using Sparkfun’s Phant on my own server but that seemed to lack features and stability. Currently I am testing ThingSpeak and letting them handle the hosting. It is open source so I could move it to my own server as well. So far the ThingSpeak looks good.

Based on the test with shorter measurement interval, I am hopeful about the radio being able to run through the long and dark winter in Finland.

Wireless MCUs and power consumption, part I

Electricity is expensive and being low power is environmentally friendly. And what is more motivating than seeing the total power consumption in real time? There are plenty of commercial products out there already but will they give you the raw data so that you can plot nice graphics? Not that many. And of course self made is always .. self made.

Lately in Finland the old electricity meters have been replaced with smart meters and they seem to have leds showing the power consumption. The model I have has a led that blinks once for every consumed watt-hour so it is easy and safe to calculate the power consumption by counting the blinks.

I am using a self designed CC430 based 433Mhz radio board and a simple photo resistor to count the blinks of the led in the apartment’s smart meter. Every minute it sends the count to another radio hooked into a Raspberry Pi that in turn sends the value to a server in the network. Then I have a simple javascript based web page that shows the data with a minute or two latency.

Power consumption over time
Javascript based power consumption info page.

There is no power plug that I could use for the radio board so it is running on two AA batteries. I put everything in a small plastic box. Below is an image of the box before I placed it next to the smart meter.

power_measure_unit-20140703

The radio part of the CC430 is turned completely off when not sending and the MCU part is sleeping. The only part running is the comparator that compares the photo resistor’s output to a predefined thresholds. If the threshold is exceeded an interrupt fires and I count the interrupts. Once a minute I reset the counter, turn on the radio and send the count over the air. Running the comparator takes some 200uA and I think I might be able to just bluntly interpret the photo resistor’s output as GPIO. That should drop the consumption below 10uA. Even with the higher consumption it has been running well for a few months now as can be seen in the graph below.

Battery voltage level
2xAA voltage level over time.

Having to replace batteries is inconvenient and another project of mine will be running outside so I can use a solar panel. More on that in Part II.

XBMC for Tegra with full HW acceleration

XBMC at UltraHD resolution.
XBMC running at UltraHD resolution on Jetson TK1.

Thanks to Markus Tavenrath there is finally a fully accelerated Kodi (previously known as XBMC) for Tegra K1 based devices like the Jetson TK1. Some of the Kodi patches are already upstreamed and the rest will be hopefully soon. Jetson supports X.Org very well and things like XRandR based TV refresh rate changes work perfectly.

I have a simple lab power supply (Mastech DF17132) and I made some quick power measurements with it. I did only guestimate the typical reading instead of making multiple tests and calculating the averages. So the numbers should be close to the truth but not scientifically accurate. I replaced the power supply that came with the Jetson with the lab power, so I have not included the consumption of the Jetson’s external power supply in the measurements.

The on-demand CPU frequency governor does not provide proper CPU clocks for smooth Kodi UI and video playback, so all the Kodi tests have been run with all four CPU cores forced on-line and with performance governor.

My USB hub, USB keyboard and USB mouse consume about 0.84W. The very noisy fan takes about 0.72W. That is about 1.5W that is included in the numbers below but maybe should not as everybody use different USB devices and nobody can use that fan in an HTPC setup.

In full screen video test cases the TV’s refresh rate has been changed to 24Hz and when the XBMC UI is visible, the refresh rate is 60Hz for 1080p TV and 30Hz for 2160p TV (HDMI 1.4 limitation).

1920×1080 Sony TV
Test case Power consumption
Slim Login 3.36
XFCE desktop, idle, ondemand 3.36
XFCE desktop, idle, performance 3.72
Kodi main menu 5.40
Kodi full screen video 1080p24 5.16
Kodi full screen video 1080p60 6.00
Kodi full screen video 2160p24 5.40

In the table below, the resolution used for all the cases is Ultra HD or 2160p or 3840×2160. The term “4k” is misleading as people often really mean the Ultra HD and not for example 4096×2160.

3840×2160 LG TV
Test case Power consumption
XFCE desktop, idle, ondemand 3.72
XFCE desktop, idle, performance 4.08
Kodi main menu 5.52
Kodi full screen video 1080p24 (max gpu clocks) 6.96
Kodi full screen video 2160p24 (max gpu clocks) 6.96

I think decoding 1080p24 with 5.16W (or 3.7W without USB peripherals and the fan) is pretty good! Add 2 watts and you get 2160p.

After watching different trailers over and over I definitely would like to see movies being produced at higher FPS rates and distributed at higher bitrates instead of bumping the resolution from Full HD to Ultra HD. That 1080p60 looked awesome.

The biggest complaint I have about the Jetson, is the fan. The noise is way too loud even for development use, not to mention using Jetson as an HTPC in the living room. There is some discussion about using passive coolers in the NVIDIA forums.

For installation instructions and other tips see the Installing Kodi wiki page.

Ubuntu on Ouya

[Update 2014-09-20]: The latest patches from Markus for the Jetson TK1 work also for Tegra3!

I was testing Markus Tavenrath’s EGL branch of the XBMC on my Ouya and noticed that OMX_UseEGLImage segfaults on Debian but doesn’t on Ubuntu. The segfault happens inside the NVIDIA’s OMX binary, so there is not much to debug. And with Ubuntu 13.10 I had rendering issues. Then I tried Debian Jessie just to discover it is already using X.Org Video ABI 15.

So here is the summary of my discoveries:

  • Debian Wheezy: Segfault in OMX_UseEGLImage with XBMC.
  • Debian Jessie: X.Org Video ABI 15, no driver.
  • Ubuntu 12.04: Old.
  • Ubuntu 12.10: Old.
  • Ubuntu 13.04: No obvious issues.
  • Ubuntu 13.10: X.Org Video ABI 14, rendering problems.
  • Ubuntu 14.04: X.Org Video ABI 15, no driver.
HW accelerated video and GLES2.
HW accelerated video and GLES2.

I noticed that Totem has moved to GStreamer 1.0 so it does not use NVIDIA’s GStreamer plugins. I changed Parole to use nvxvimagesink instead of the de-facto xvimagesink and it works well. I’ve uploaded the binary to my tmp.

Pulseaudio seemed to cause slow playback and extra CPU consumption so I just removed it.

My instructions for creating Ubuntu Raring rootfs for Ouya can be found from github. Do leave a comment if there is anything broken with the instructions!

Steam on Debian Stable

I like the idea of being able to play games on Linux, so the announcement of Steam for Linux was a big thing. Too bad Debian Stable has too old C-library for it. During the past year I’ve occasionally tried to get Steam running on Debian Stable (Wheezy) with usually little success. Currently I think installing Debian Testing (Jessie) to a chroot is the most easiest way. It is not as complicated as it may first sound.

One catch is that you need to be running the same version of NVIDIA’s drivers inside the chroot and outside of it so they need to be built.

On my gaming PC I use self-compiled kernel and the latest drivers from NVIDIA. On my media box in the living room I have some old integrated NVIDIA chip. Trine 2 runs nicely on my Gaming PC (GTX 760) and awfully on the integrated chip. I assume it’s about the chip and not about the different driver version (319.72 vs 331.20) and I doubt I’ll install the latest drivers just to verify that.

Update NVIDIA drivers from Jessie:
(Updated 11.06.2014)

Inside the chroot:

$ cd $HOME
$ mkdir nvidia
$ cd nvidia
$ apt-get source nvidia-driver

And then outside the chroot:

$ cd $HOME/nvidia
$ cd nvidia-drv-
$ dpkg-buildpackage -b
$ cd ..
$ sudo apt-get install -t wheezy-backports module-assistant
$ sudo dpkg -i *deb

It’s not mandatory to use Debian packaged NVIDIA drivers. Just be sure to install the same NVIDIA driver package inside the chroot that you are running outside with the 32bit OpenGL libraries. You should skip installing the kernel module inside the chroot:


$ sudo sh NVIDIA-Linux-x86_64-331.20.run --no-precompiled-interface --no-runlevel-check --no-kernel-module --no-x-check --no-kernel-module-source --no-distro-scripts --no-nvidia-modprobe --accept-license

If you see “ERROR: Unable to create ‘(null)’ for copying (Bad address)” just hit OK several times. Also you may need to add /etc/ld.so.conf.d/nvidia.conf with “/emul/ia32-linux/usr/lib/” in it and run “sudo ldconfig” after adding it.

Create Jessie schroot

These instructions are adapted from https://wiki.debian.org/Schroot and assumes 64bit host Debian.

WARNING: removing schroot with “rm -rf” while it is active will delete your home directory as well! You should reboot and make sure there is nothing mounted inside the chroot before removing it.

Install schroot for chrooting and debootstrap for creating the Jessie root filesystem:


$ sudo apt-get install schroot debootstrap
$ sudo mkdir -p /srv/chroot/jessie

Create the Jessie rootfs (the last parameter is optional for faster downloads):


$ sudo debootstrap --include sudo jessie /srv/chroot/jessie http://ftp.[your country domain here].debian.org/debian/
$ sudo mkdir /srv/chroot/jessie/run/shm
$ sudo chmod 1777 /srv/chroot/jessie/run/shm

Configure Jessie schroot (note that you need to add your user account’s group name in there):

$ sudo vi /etc/schroot/schroot.conf


[jessie]
description=Debian Jessie (testing) 64-bit
directory=/srv/chroot/jessie
type=directory
groups=[your group name]
root-groups=root
aliases=default
personality=linux
preserve-environment=true


$ sudo vi /etc/schroot/default/fstab
# Uncomment /run/shm

The /etc/group is shared between the chroot and the host Debian. Rest of the instructions assume your account belongs to the sudo group:

$ sudo adduser [your user name] sudo

Finishing the schroot

Schroot into Jessie and verify sudo:


$ schroot
$ cat /etc/debian_version
# Should say Jessie
$ sudo -l
# Should show that you can run ALL

Configure APT to use non-free packages and multiarch with i386:


$ sudo vi /etc/apt/sources.list
# Append "non-free contrib"
$ sudo dpkg --add-architecture i386
$ sudo apt-get update

Install Steam from Jessie and some dependencies:


$ export LC_ALL=C
$ sudo apt-get install python xdg-utils less libvdpau-dev libalut0 pciutils lsb-release libopenal1:i386 libvorbisfile3:i386 libglu1-mesa:i386 build-essential libgl1-nvidia-glx:i386 libgl1-nvidia-glx:amd64 steam
$ exit

The schroot is now ready and you can launch Steam directly from the host Debian:
(Updated 11.10.2014, See github issue for details)

schroot
sudo /etc/init.d/dbus start
steam

If you spot a mistake in the instructions do leave a comment below so I know to fix it.

My first 3D print

Mechanics has always been a problem in my robotic projects but now that the 3D printing is such a hot topic I decided to test it out.

It seems that the 3D printing services use STL format and many of the popular 3D modeling applications can export it, so there are plenty of applications to choose from. I wanted to use Blender for the modeling as I have used it briefly in the past and I would like to know it better. It was easy to use boolean operators to shape my model but it turned out that even though the model looks nice on the screen, it is not enough for real world printing. I had some broken surfaces, holes, etc. in there. As I am a Blender rookie I ended up creating the simplest cylinder and modifying its subdivided surfaces to shape my model. Easy and quite fun :)

Now that I had the model, the next step was to print it. The nearby public libraries provide 3D printing services for free or nearly free with printers from MakerBot and MiniFactory. After a couple of visits I realized that it is not that easy to jump into the 3D printing world with them. You need to know how to tune the parameters of the software, how to clean up and prepare the printer, how to preheat it, etc. You also need to model your creation in such a way that the printer can print it. The plastic is hot during the printing and not very strong so you may need to add some supporting structures during modeling. At least some of the 3D printer applications can add the supporting structures automatically but I was told they might not be very good at it.

Below is a photo showing the first three layers of an automatically created supporting structure. That looked OK but the actual model started to go wrong already on the first layer so the printing was canceled.

First layers of a 3D printed supporting structure.
First layers of a 3D printed supporting structure.

After a couple of miserable failures somebody hinted that Shapeways is a much easier way to get 3D prints and the price is low enough. They seem to be using selective laser sintering and I didn’t need to worry about supporting structures or fine tuning parameters. They also have a bunch of different materials and colors to choose from. I chose “Coral Red Strong & Flexible Polished”:

3D printed Camera Housing
Original part and the 3D printed version with my additions.
3D Printed Camera Housing Fits
The 3D printed part fits perfectly.

I have used cable ties and Meccano parts earlier but I needed something more lightweight (and better looking) and the Shapeways might very well be the solution for me.

Debian on Ouya: All Systems Go

I finally got all the major subsystems working and Debian is now usable on Ouya. I prefer Debian but Ubuntu should work similarly.

Working video and 3D

In the above screenshot I’m playing 1080p H264 while running glmark2-es, an OpenGL ES benchmark. And the CPUFreq ondemand governor doesn’t even raise the CPU frequency from the minimum as everything is properly accelerated. I do have to admit that the 1080p video isn’t running smoothly with the benchmark running at the same time.

A disclaimer before telling more: Trying this out might void the warranty and flashing anything to Ouya may easily brick it forever. So don’t try it, unless you are willing to buy a new one.

That said, the idea is not to touch Ouya’s Android at all. Kernel is booted from RAM and Debian from an SD card or USB stick.

The instructions for debootstrapping your own Debian Wheezy rootfs are described in the github repository and the needed binaries are in a temporary location that will probably change at some point.

WiFi is working as well but I’m not sure if the firmware binaries are redistributable, so you need to copy them from the Android rootfs after booting to Debian.

One of my main goals for this whole exercise is video encoding and I’m happy to say that H264 encoding from an USB webcam works nicely with hardware acceleration as well.

I’ve also noticed some issues:

  • Hciconfig doesn’t show BT devices, I didn’t debug much further.
  • Mpg123 seems to play but nothing is heard. Maybe it tries to pass MP3 onwards instead of PCM? GStreamer provides acceleration for MP3 and AAC though.
  • Video acceleration works only with GStreamer and nvxvimagesink. Mplayer can’t even use XV video output correctly.
  • Tegra3 supports only OpenGL ES 2.0 with EGL, so no full OpenGL with GLX.
  • Xrandr seems to be able to switch the resolution but after the switch there was window decoration corruption.

Despite the deficiencies I think Tegra3 is quite well supported in the X.Org world and many things work well with this 99$ device.

If you test my instructions, let me know how it goes and what you think about it! :)

Pleco Phase02 completed

It’s been two years already since I posted about Phase01 being completed. It was a simple track based vehicle using cheap DC motors and the hull was built from Meccano parts:

Pleco Phase01

For Phase02 I decided to go with a ready made car and bought an RC Rock Crawler. It’s about four times the size of the Phase01:

Pleco Phase02 open

Pleco Phase02

The software is roughly the same as it was for Phase01. I’ve fixed a lot of bugs, simplified some things and added a bunch of new features. The slave has a sonar next to webcam and it measures the distance to what ever the camera is pointing at. The slave also measures the current consumption and battery voltage level. All details are shown on the GUI.

The hardware on the other hand has changed a lot. Instead of handling the servos directly from Linux there’s now a separate self-designed Cortex-M4 based microcontroller board for driving the PWM signals. In the future the microcontroller can update the PWM signals real-time based on other sensors without having to worry about latency issues in Linux.

The Linux is now running on a Tegra3 based Ouya gaming device. Ouya is not as convenient for robotics as Gumstix was but personally I think Tegra has better Linux support than OMAPs. And since there is now a separate control board for motors and sensors, it’s enough for the Ouya to only have a USB connection to the control board.

Ouya needs 12 volts while the motors need 5 volts and I’m expecting to need 3.3 volts as well. So I now have three switching regulators connected to the battery for the needed voltage levels. And a USB hub because of the USB based control board and webcam. There are also lots of cables. So I’m not actually able to get everything nicely inside the car, but almost.

Controlling an RC car with a keyboard is inconvenient, so I’ve added support for gamepads. I’m currently using a Bluetooth based gamepad from Logitech:

Logitech F710 gamepad

When driving in a local WiFi network, there’s no noticeable latency at all. It’s still not possible to really drive based on the camera only, the viewing angle is too narrow, turning the camera is cumbersome and the video quality needs some tweaking.

Now that I’ve made some nice progress with the project, I have clear goals for the Phase03:

  1. Disassemble the webcam to get the size and the weight down and to be able to attach fish eye lenses to it.
  2. 3D print a frame for the electronics and the webcam.
  3. Tweak the video quality and camera controls so that it would finally be possible to drive based on the video stream.
  4. Control the webcam based on driver’s head orientation?

So there are plenty of interesting things to learn :)

Oh, and I’ve moved the code to github.

Debian on Ouya

Ouya

Ouya is a 99$ Tegra3 based gaming console without a display.

My goal is to use Ouya in my robotics project for video encoding but first I want to have Debian running there with hardware accelerated X.Org, OpenGL ES and video.

I now have the Debian running but with a few bigger issues that I’ll describe shortly. If you want to try it out, you can find my instructions for creating the rootfs in github. That might void the warranty even though the kernel is booted from RAM and the rootfs mounted from USB stick so the Ouya software should remain intact.

Ouya is easily brickable permanently, so you need to be careful not to flash anything there and you’ll be doing it at your own risk.

About the Issues.

HDMI

2013-09-05: HDMI works now with multiple resolutions and is not so picky about having the cable connected already on boot.

Ouya display kernel driver is hardcoded to use HDMI as the primary display with 1920×1080 resolution. That works relatively well as long as you keep your monitor/TV always on. I couldn’t get anything but black if I e.g. switched my monitor to another input and back.

I tried to enable the normal behaviour in the display driver and by disabling the LVDS in xorg.conf but the TV remains black and doesn’t seem to change the resolution. Maybe there is still something hardcoded in the display driver or maybe the driver is trying to enable the non-existent internal panel and gets confused.

Audio

2013-09-11: Got audio working with a simple asound.conf. I also run /etc/init.d/alsa-utils stop but unsure if that affected anything.

aplay -l lists HDMI as the first device and tegrawm8903 as the second. If I make the tegrawm8903 the default the audio plays but only from the left speaker and half the speed.

I don’t know if this is related to the HDMI problems above or if I should just have the correct ALSA mixer configuration.

Video

2013-09-05: Totem has configurable video sink: gconftool-2 -s /system/gstreamer/0.10/default/videosink nvxvimagesink –type=string

Hardware accelerated video decoding and rendering is supported through GStreamer. Currently videos play well with playbin2 as long as the audio is disabled with audio-sink=fakesink and the correct video sink is selected with video-sink=nvximagesink.

Maybe the GStreamer’s autovideosink should be patched to use nvxvimagesink instead of xvimagesink to make nvxvimagesink the default in applications using playbin2

Power

2013-09-05: CPUfreq with ondemand governor is working and enabled in the kernel nby default now.

CPU core hot-plugging works but switching to the low power core seems to lead to a kernel bug (arch/arm/mach-tegra/pm.c:509). Same bug seems to happen with ondemand CPUFreq governor. I haven’t really tried to get those working yet but both of them are working with Nexus7 so maybe it’s possible to get them working on Ouya as well.

If you want to test Debian on Ouya, you can find the needed blobs from my /tmp but I might set up something more appropriate later.