Monday 27 January 2014

Raspberry Pi GPS Helmet Cam

I've been snowboarding for the past 20 years, and for most of that time I've been video'ing mine and my buddies adventures with a helmet cam. An old video of me snowboarding in Morzine, France.

I wanted to make my own helmet cam which would also show data about what was going on (e.g. speed, altitude, temperature).
Raspberry Pi GPS Helmet Cam

The starting point was my Raspberry Pi GPS Tracking Car Dash Cam, this gave me some code for gathering GPS data, recording video and generating data overlay video's.

I came up with a 1 led, 1 button design; the led flashes when the cam is 'ready' (quickly when there isn't a GPS fix, slowly when there is GPS fix), the led comes on when the camera is recording, a short button press starts / stops the camera and a long button press shutdowns the helmet cam.

I set about writing the code which would run at start-up of the Pi and control the camera, waiting for the button to be pressed, controlling the led, reading the GPS data and temperature data and start / stop the camera.

The program is multi-threaded and simply starts up a thread for each 'thing' (led, button, GPS, temperature sensor) that needs to be 'controlled', the main program then polls these controllers asking them if anything has changed and acts accordingly (e.g. starting / stopping the camera, shutting down the pi).

When the camera is started , the program uses the excellent python module, picamera, to start the video capture and writes the gps and temperature data to a file while the video is recording.  I made a change to the picamera module (which has since been introduced), this gave me a function to read the current frame number while the video was being recorded, allowing me to sync the data I have read to an exact position in the video.

I then use the data file to create a data video which I ultimately overly on top of the video taken from the helmet cam.  The data video is created in exactly the same way as my Raspberry Pi GPS Car Dash Cam, by creating individual images for each frame using PIL (python imaging library).


A single frame image from a data video

I then use mencoder to join the images together into a single video.

Hardware
The helmet cam is a Raspberry Pi model A inside a small sandwich box, a control box and a Raspberry Pi camera board on the end of a long ribbon cable.



The control box houses an Adafruit Ultimate GPS breakout board, a waterproof led and button, a temperature sensor and a very badly soldered piece of strip board which ties it all together.

It was my first time using stripboard, so moving my breadboard build to something more robust was a big job for me, but armed with a piece of paper and a set of crayons I came up with a design!



The camera is mounted on a small piece of wood, cut so when its mounted on my helmet, it, roughly, points in the right direction.

I got a 1m cable for the camera which I shielded with tin foil, as without it, it caused the GPS unit to loose fix when it was recording and then wrapped it in a polyester braided sheath.


The camera, mount and cable are then attached using sticky backed velcro to my helmet, so I could take it off when not in use.

The whole set-up was powered by a usb power bank.

Code
https://github.com/martinohanlon/pelmetcam

There are a number of python modules which make up the helmet cam code:
- pelmetcam.py - this is the main program which controls the helmet cam
- tempSensorController.py - module which continually reads from the temperature sensor
- GPSController.py - module which continually reads from the GPS sensor
- createDataOverlay.py - module which creates the data overlay images

I also created a few bash scripts to make things easier to manage:
- runPelmetcam.sh - this is run when the pi boots and starts up the helmet cam, including the GPS daemon, temp sensor modules and shuts down the pi when the program finishes
- runPelmetcam.init - init.d script to make runPelmetcam.sh run at boot, see this post for information on running commands at boot
- createVideos.sh - runs the commands to make the main video into an MP4, creating the data overlay images and encoding them into a video file

Challenges
Before I went away I wanted to make sure it would operate in cold weather and test simple things, like my code would work if temperatures went negative, unfortunately an unusually mild winter in the UK mean't the only thing I could do was stick it in the freezer!  It performed perfectly for the 20 minutes I left it in there.  I can also confirm that the light does go off when you close the freezer door!


After the unit had been on for a while I started to notice that the temperature sensor was reporting temperatures much higher than expected (i.e. +9 C when it was -5 outside), I don't know for sure but I'm pretty sure the GPS unit generates a little bit of heat, which obviously when trapped inside a small sealed box warmed it up a bit!

If I was to do it again I wouldn't bother putting the GPS unit in the control box; it seemed like a good idea due to the interference the camera creates and a desire to have it 'outside' to get a better GPS fix, but with the shielding on the camera cable and the sensitivity of the GPS Unit, I didn't need to worry.

There is a current bug in the raspberry pi firmware which means if you try to use the raspberry pi camera at the same time as using a 1-wire sensor (like my temperature one) the camera will fail to start up.  There are several reported workarounds, in the end I ended up reverting to an old firmware which didn't suffer from this bug.

Stability
I wasn't expecting my Pi powered helmet cam to be very robust, I was secretly only expecting to get 1 or 2 runs out of it.  I thought the combination of wet conditions, very cold temperatures, dodgy wiring / soldering and some pretty aggressive snowboarding would mean that it just self destructed.

However, it proved to be very robust, I used it all week and recorded hours of footage with the camera.

The only component which failed was a cheap micro usb power cable which split and caused the pi to boot and reboot continuously as it shorted out, ultimately leading to a corrupt file system.

Full Length Videos
You can watch the unabridged videos taken using the helmet cam on my youtube channel:

Les Deux Alpes 2014 - Snowboarding "Vallee Blanche Off The Side"
Les Deux Alpes 2014 - Snowboarding - "Boarder Cross Lee Wins"
Les Deux Alpes 2014 - Snowboarding "Under the Vandri Lift into the Trees"
Les Deux Alpes 2014 - Snowboarding "Piste Down To Lac Noir Lift"

Shopping List
I was asked what 'bits' you need to create your own helmet cam.  A lot of these bits I already had, but I think this is a complete shopping list:
- Raspberry Pi - Model A
- Raspberry Pi - Camera Board
- Sandisk Class 10 32GB SD Card
- Adafruit Ultimate GPS Breakout Board (UK, US)
- Waterproof Push Button
- Waterproof Ultrabright Red LED
- Electronic Project Enclosure
- 1m ribbon camera cable
- Tin Foil (for shielding camera cable)
- Portable Battery Charger USB Power Bank
- 15mm Polyester Braiding
- 8m Polyester Braiding
- DS18B20 Temperature Sensor (UK, US)
- 4.7k resistor (for temperature sensor)
- 10k resistor (pull down for button)
- ?k resistor (appropriate for your LED)
- Stripboard
- Plenty of wire

53 comments:

  1. Lucky! I never really got to snowboard... We don't really live anywhere cold with snow.

    ReplyDelete
  2. martin, i go away to alpes d'huez in 11 sleeps. is it feasible to make this work in that amount of time?

    ReplyDelete
    Replies
    1. If you have already got the bits then, yes, I dont see why not. The only build is the control panel and camera cable and mount. If I had my time again would only put the button and the led into the control panel and leave the GPS receiver in with the Pi, which would simplify things. It just a question of whether you could get all the bits!

      If you interested, Ill try and pull together a shopping list and include it in the post.

      Delete
    2. I'd definitely be interested. Im on pimoroni now, trying to work out exactly what i need.

      The first image makes it look as if the camera wasnt pointing forwards, looks more up to the sky. was that right? or a testing version?

      Delete
    3. Ive added a shopping list for you. For most of the commodity items (braiding, buttons, led's), ebay will be your friend!

      Delete
    4. What's the best source for long camera ribbon cables? The usual suppliers don't seem to have anything longer than ~50cm.

      Delete
    5. Ebay 100cm cable http://www.ebay.co.uk/itm/141129552486?var=440217712404&ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

      Delete
  3. The camera seems to work well. I remember reading something that suggested the cable supplied with Pi Camera is short because there are performance issues with longer cables. Did you experience any?

    ReplyDelete
    Replies
    1. No, nothing. There are pictures on the forum of people using VERY long cables.

      Delete
    2. Good to know. Great article Martin. Thanks.

      Delete
  4. Awesome project, thanks for sharing. Planning to incorporate some of your code for my GPS rover..

    ReplyDelete
    Replies
    1. Excellent, I look forward to seeing it in action.

      Delete
  5. works it with a raspberry pi model b

    ReplyDelete
    Replies
    1. Yes it works fine with a Model B, it will just use more power. The model A uses about half the power of a model B.

      Delete
    2. tnks voor the quick reply.
      I follow you for a while and would like to give something back to the things you do for us.
      I'd like to make you totally free a website.
      Aleen hosting fees.
      please contact me via google+ as you may want to
      sorry for bad english

      Delete
  6. Hi Martin.. This is brilliant and thanks for being so generous with your info. I was looking for a project learn how to use GPS and a Raspberry Pi and by coincidence am going skiing next week so this was perfect! I have mostly got my version working but I was wondering if you could help with the overlaying of the videos. I am at a stage where I get two videos but am a bit confused how you overlay them? Any help would be great, Thanks

    ReplyDelete
    Replies
    1. Hi Doug,

      Im glad you have found it useful, Im also really pleased you have built your own. I would love to see the results, do you have a blog or anything?

      Anyway to overlay! I actually use Microsoft Expression Encoder 4. Its a free video encoder and actually a pretty good one. http://www.microsoft.com/en-gb/download/details.aspx?id=18974

      There is an option when you encode a video to do a video overlay, you can also set a level of transparency too. This is what I used to bring the helmet cam video and the data video together. You could use ffmpeg on the pi, but it will take AGES to encode, my advice, copy it onto something with a little more power to do the encoding.

      Hope that helps.

      Mart

      Delete
    2. Mart,

      Oh, I see, thanks. I downloaded Expression last night so will have a play with it today and certainly upload some videos when I have something decent to share..

      Thanks again,

      Doug

      Delete
  7. Hey Martin,

    I love the tutorials you are posting, and I really like your code! I am having some trouble, and I really hate to bother you with this, but I have been at my project for days now and really dont know where else to go.

    first, I dropped kernel version to 3.6 like you recomened ( i was hitting the temp single line probe issue). I used your pelmetcam repo as well as your picamera fork. I believe i have most everything working, but I keep getting this error everytime i push the record button

    mmal: mmal_vc_port_parameter_set: failed to set port parameter 32:2:ENOSYS
    Unexpected error - Unable to set inline_headers: Function not implemented

    I have searched high an low for a fix but the only thing i hear is "upgrade firmware" but i really dont want to for the same reason i backed down from the 3.10 kernel.

    I did the sudo python setup.py install for the picamera in the picamera dir, i just dont know what is causing this error or how to adress it. did you bump into this? do you have any recomendations? thanks, and again, sorry for the trouble.

    ReplyDelete
  8. Right... I think! We are going back a while that i needed to find a version of the kernel which supported inline headers but didnt contain the 1-wire bug! It was a right pain. If you look in the github readme, i give the specific kernel build i used, are you using this one?

    04/01/2013 Due to an error with the rpi kernel, https://github.com/raspberrypi/linux/issues/435 you need to use kernel version Linux picam 3.6.11+ #557, until the bug is fixed downgrade kernel with command sudo rpi-update 8234d5148aded657760e9ecd622f324d140ae891

    ReplyDelete
  9. yup, that build is the magic one! looks like I was running a 3.6.11+ kernel that was just a few builds newer. Thanks a bunch man. let me know if I can return the favor.

    ReplyDelete
    Replies
    1. Just let me know if you manage to get the cam built and it would be good to see some uploaded video.

      Delete
    2. for sure, I am installing it into my motorcycle. so far I got video, gps and therm. I just need to figure out how to tweak the overlays and stitch them together. then of course, overlap. Did you ever look into actually super imposing the overlay gps ontop of the actual h264 frames themself. From what i hear, python can ca do that, but im still new to multimedia and python.

      Also, I wrote a script that builds kml files for google earth. If you would like I can send that to you when i get it working with your csv. it takes all the gps plot points and draws a red line along the path and is viewed through google earth. I am using it specifically for trip tracking for my bike.

      Delete
    3. I looked many times at overlaying the data in real-time. Im sure it is possible, but outside my realm of experience or level of interest to try and solve the issue.

      The key sticking point seems to be getting the GPU rather than CPU to do the work, as if you try and do the overlay in the CPU it wont be quick enough.

      I spoke to Dave Jones who created picamera and its a task he has on his list for inclusion in a future version of picamera, till then or someone else provides a solution Im happy to do any overlay in post production.

      On the subject of data overlay in post production, I used Microsoft Expression Encoder, its pretty good and really simple to use.

      Delete
    4. Hey Martin, How did you tweak your overlay to be transparent?

      I tweaked the overlay.py script to make the background of the image transparent, and the PNGs it spits out look good with transparent backgrounds, but it seems like the minute I make the data.avi with mencoder, it makes everything that was transparent... black. any ideas?

      Delete
    5. I could never work out how to make movies with transparency, it only seems to be supported by a handful of codecs.

      So, I added the transparency in post production when I overlayed the data video onto the camera video. I used Microsoft Expression, setting the background colour to transparent and the transparency is one of the advanced settings.

      Delete
  10. Hey Martin,
    I finally got my project running properly. Here is my first trip video with my tweaks to the overlay.

    https://www.youtube.com/watch?v=vdhmsMJTaks&list=UUUgc9Fi1Ftu0c05wlhRrDgw

    ReplyDelete
    Replies
    1. Thats great. I'm pleased you modded the overlay to fit your needs. Absolutely fantastic. The only thing missing is a link to the original project ;)

      Delete
    2. I will take care of that ;)

      Do you experience frame drops for about a second every 30 seconds? I am going to turn down the resolution a bit to see if I can get the video a little smoother. I wish I could post my KML files, those are really fun to look at over Google Earth.

      Thanks again for the code! I finally got a better mount. once the rain stops, I am going to put it on my motorcycle and see how it goes!

      Delete
    3. I occasionally get frame drops, but i found as long as i stuck to 25fps it was ok, what sd are using, if might be worth investing in a good high capacity class 10.

      If you can upload the klm files somewhere it would be good to see them. Maybe google drive or dropbox?

      Delete
    4. Hi Martin,

      I have a class 10 right now, but it still see too much skipping.

      I uploaded one of my KML files to my webserver:
      http://t3chkommie.com/opensource/trip.kml

      The KML file is generated by a python script I wrote that rips through your CSV file and creates the overlay and dumps it in the directory the CSV is found. Similar to your createOverlay python script.

      You will need to open it in Google Earth. But i think it is something really neat to add to the project. I noticed Sony has come out with something very similar for $300+ It would be neat if we could build a PelmetCam image for those who want to install and go :) just an idea.

      Delete
  11. Hi Martin,
    i've used a piece of your code on capture video and save framenumber on a file.
    What i don't understand is, that i see on that file each frame repeated more than one time.

    in attach my python code:
    #!/usr/bin/python

    import os
    import time
    import sys
    import picamera

    VIDEOFPS = 30
    VIDEOHEIGHT = 1080
    VIDEOWIDTH = 1920

    try:

    with picamera.PiCamera() as camera:
    camera.resolution = (VIDEOWIDTH, VIDEOHEIGHT)
    camera.framerate = VIDEOFPS
    camera.vflip = True
    camera.hflip = True
    camera.video_stabilization = True
    camera.start_recording("vid.h264", inline_headers=False)
    print "Recording - started pi camera"

    while True:
    framenumber = camera.frame
    print str(framenumber)

    camera.stop_recording()
    camera.close()

    except KeyboardInterrupt:
    print "User Cancelled (Ctrl C)"

    finally:

    print "Stopped"

    could give me an help ?

    ReplyDelete
    Replies
    1. You are getting frame numbers repeated because your program is reading and print the frame number more than 30 times a second.

      Delete
  12. Hi, i am complete newbie to rasberry. rally liked your project and want to do the same.
    I might sound stupid but wasnt sure about what OS you are using for it.thnx

    ReplyDelete
  13. Hey Martin,

    I recently acquired a 3d printer and am now putting my pi and its parts in a custom case for this GPS trip-tracking dash cam project for my bike. You can check it out here if you like. Interested in your thoughts.

    https://t3chkommie.com/motorcycle-case-for-raspberry-pi/

    ReplyDelete
  14. Hello,

    I'm having problem with the creating of the overlay movie :-(
    Always the same error...

    Traceback (most recent call last):
    File "/home/pi/dev/pelmetcam/createDataOverlay.fullData.py", line 176, in
    datadrawer.newDataFrame(int(dataitems[0]),
    ValueError: invalid literal for int() with base 10: 'PiVideoFrame(index=0'

    A movie of my raspberry cam (cam is build-in in my helmet)
    https://www.youtube.com/watch?v=1tI0OwBI9Bk

    ReplyDelete
    Replies
    1. You are getting the error because its trying to convert "PiVideoFrame(index=0...." into an integer. Im guessing you used the latest version of picamera. When i created this picamera didnt support getting the 'frame count' so I used a modded version of picamera to do this. You need to change line 176 to pull the frame number out of the "PiVideoFrame(index=0..." text. Which, from looking at the picamera documentation is the "index".

      Delete
    2. Thank you for your reply.
      It doesn't work.. Now i have Always Floating errors.
      Can you send me a working file?
      I'm right now in Les 3 Vallees (Val Thorens France).. I like to test it.

      Delete
    3. Hellow folks, you'll need substitute the line 262
      dataString = str(framenumber) by
      dataString = str(camera.frame.index)

      Delete
  15. This comment has been removed by the author.

    ReplyDelete
  16. Hey Martin!

    Great Project! I am almost ready to go but have a question:
    I download you scripts but i am not shure where to place them on my raspberry

    hope to hear from you

    willem

    ReplyDelete
    Replies
    1. I think you can probably put it where you want. From memory I think I put it in:

      /home/pi/dev/pelmetcam

      Delete
    2. I tried that but when i start Up mij raspberry iT doesnt run your scripts at boot. Cant quite figure out what the problem is

      Delete
    3. The program needs to be set to run at startup by creating an init.d script, see this post for more info http://www.stuffaboutcode.com/2012/06/raspberry-pi-run-program-at-start-up.html, there is an init.d script called runPelmetCam.init

      Delete
    4. I created that script in /init.d but stil no succes. I'm going to try it again tonight with à clean raspbian os

      Delete
  17. Btw... Is iT necessary that all the hardware is connected? I'm not using the Temp sensor and i am not shure that my GPS is working 100%

    ReplyDelete
    Replies
    1. No idea... I suppose there is a chance the code wont run. Although I suppose there is a chance the code wont run anyway, I havent tried it in over a year! ;)

      Delete
    2. Oke, id like to use it for my skiing trip in a few weeks. Seems like i have to work hard for it :)

      Delete
  18. Martin, thanks for writing and documenting this project. I've just started a build of this on Raspberry Pi 2 which obviously uses the new version of picamera - as such I've run into a few of the problems mentioned here by others. Luckily I've managed to get around them and I've blogged about them in the hope that he'll help others :)

    http://www.nigelpond.com/2015/02/28/raspberry-pi-2-gps-helmet-cam/

    ReplyDelete
  19. Great project, congratulations!

    ReplyDelete

Note: only a member of this blog may post a comment.