{"id":411,"date":"2012-04-15T16:10:53","date_gmt":"2012-04-15T21:10:53","guid":{"rendered":"http:\/\/hillelsteinberg.com\/?p=411"},"modified":"2016-02-19T20:13:31","modified_gmt":"2016-02-20T01:13:31","slug":"diy-miniature-panorama-collection-system","status":"publish","type":"post","link":"https:\/\/analyze3d.com\/Blog\/?p=411","title":{"rendered":"DIY Miniature Panorama Collection System"},"content":{"rendered":"<p><a href=\"\/Blog\/wp-content\/uploads\/Beagle1.jpg\"><img decoding=\"async\" class=\"aligncenter\" src=\"\/Blog\/wp-content\/uploads\/Beagle1.jpg\" alt=\"Miniature BeagleBoard Panorama Capture System!\" width=\"540\" \/><\/a><\/p>\n<p>So Google didn&#8217;t hire you, but you still want to do cool things like engineer a miniature device to capture indoor 360 degree panoramas. Not to worry. The key to reaching this challenge lies in the art of breaking down goals into manageable pieces. You&#8217;ll need to build these pieces separately and then integrate. Finally, you can iterate your results stepwise toward perfection.\u00a0 While your device is short of perfection, however, you should probably call your progress &#8220;Beta&#8221;.<\/p>\n<p>First, you&#8217;ll need a small computer platform to do the work on. This platform needs to be mobile so size is key. It will need to be powered by a portable battery source, and provide a wireless connection for access from your mobile device (e.g. phone). An <a title=\"The Arduino Platform\" href=\"http:\/\/www.arduino.cc\/\">Arduino<\/a>, <a title=\"The BeagleBoard Platform\" href=\"http:\/\/beagleboard.org\/\">BeagleBoard<\/a>, or <a title=\"The Rasberry PI Platform\" href=\"http:\/\/www.raspberrypi.org\/\">Rasberry PI<\/a> will do. For the purposes of this entry, I&#8217;ll just use the BeagleBoard TI ARM Cortex platform because, at the time of writing, it is currently the most capable and accessible of the three.<\/p>\n<p><!--more--><\/p>\n<p>Before You begin in earnest, you will need to upgrade the OS provided with the board.\u00a0 The demo Angstrom build provided with the BeagleBoard is, to be honest, quite minimal and a bit outdated.\u00a0 A better bet is to grab a new 16gb MicroSD card and put the latest Ubuntu on it using instructions found <a title=\"Ubuntu on a BeagleBoard\" href=\"http:\/\/elinux.org\/BeagleBoardUbuntu\">here<\/a>.<\/p>\n<p>Once you have booted into Ubuntu, don&#8217;t forget to do an &#8216;apt-update&#8217; and then an &#8216;apt-upgrade&#8217; to ensure you have the latest software components.\u00a0 You will need to get &#8220;wireless&#8221; working early so you won&#8217;t need to drag a monitor\/keyboard\/mouse around with this device each time you deploy it.\u00a0 This will probably involve modifying the \/etc\/network\/interfaces and \/etc\/wpa_supplicant files.\u00a0 Remember, &#8216;dmesg&#8217;, is your friend.\u00a0 Look around the web and you will find a lot of information on getting the wireless to work.\u00a0 The trick is to get a WIFI dongle that is small and yet fully supported by your Linux kernel.  Make sure to use encryption, because you will be transmitting many images of the interiors of your location.<\/p>\n<p>After you can connect remotely to your BeagleBoard, the next thing to try is to get a small webcam working with your Linux.\u00a0 You will need the lightest, smallest, highest resolution webcam you can find with reasonable driver support in Linux.\u00a0 You can use the video4linux API to access your webcam.\u00a0 You will know when you have the camera working in Linux when you see a \/dev\/video0 device file appear and executing the &#8216;dmesg&#8217; command confirms that the webcam was detected.<\/p>\n<p>There are many examples of video4linux code on the web that can capture a webcam image.\u00a0 Use a web example to create a function that simply grabs the highest quality picture you can get from the webcam and outputs it to a directory specified with a numbered filename.\u00a0 The file format can be JPEG, but don&#8217;t forget to use the highest (100%) quality settings because this is a lossy format.\u00a0 Test the new function by creating a driver to iterate several times.\u00a0 Try to make the capture system faster by carefully separating the &#8216;snap&#8217; logic from the initialization logic.\u00a0 Then you can initialize once, and snap quickly.\u00a0 Make sure the files are written out correctly too, and none are missing when you complete.\u00a0 You will probably need to disable auto-gain, auto-white balance, and other parameters in the camera initialization code which will cause problems for stitching later.\u00a0 Video4linux has calls to get\/set these parameters.\u00a0 There are plenty of examples on the web to show you how this is done.<\/p>\n<p><a href=\"\/Blog\/wp-content\/uploads\/Beagle2.jpg\"><img decoding=\"async\" class=\"aligncenter\" src=\"\/Blog\/wp-content\/uploads\/Beagle2.jpg\" alt=\"Miniature BeagleBoard Panorama Capture System!\" width=\"540\" \/><\/a><\/p>\n<p>To move the camera, you will need a pair of reasonably powerful servos.\u00a0 A pair of Hitech\/Futuba servos will do as well as this <a title=\"Pan\/Tilt Servo Holder\" href=\"http:\/\/servocity.com\/html\/spt100_pan___tilt_system.html\">contraption<\/a> to assist with the pan\/tilt motion.\u00a0 Once you have put the two servos together, you will be wondering how the BeagleBoard will tell them to move.\u00a0 No problem.\u00a0 First, buy a servo controller such as the <a title=\"The Maestro 12  Servo Controller\" href=\"http:\/\/www.pololu.com\/catalog\/product\/1352\">Maestro 12 Channel<\/a>, and hook it up to the BeagleBoard via a USB cable.\u00a0 This cheap servo controller board when connected to the BeagleBoard should cause the Linux kernel to report (see &#8216;dmesg&#8217;) a new CDC ACM device, and the interface file \/dev\/ttyACM0 should appear.\u00a0 You can then hook the pan\/tilt servos up to the Maestro on channel 0 &amp; 1.\u00a0 You will need at least a separate 5v supply just to power the servos.\u00a0 You can do this by either using a single four AA\/AAA battery pack or a two AA\/AAA battery back with a voltage doubler.\u00a0 Your call.\u00a0 The four pack is heavier, but it&#8217;ll last longer.<\/p>\n<p>There are many examples of code on the web that you can use to get your Pololu servo controller up and running.\u00a0 You should first use the included graphical Maestro configuration tool to set the servo to USB chaining mode.\u00a0 You can then experiment with the two servos to find and note their appropriate min\/max values. \u00a0 You can use the code examples on their site to create a function that quickly points the servo towards a particular azimuth\/elevation angle.\u00a0 Depending on your servos and your pan\/tilt holder, you may not have a full 180\/360 solution.\u00a0 Not to worry, you can iterate your design later.\u00a0 Again, separate the servo controller initialization code from the actual pointing functions.\u00a0 This will come handy during the integration phase.<\/p>\n<p>You will next need to mount the camera on the pan\/tilt holder.\u00a0 Initially, I recommend simply using &#8216;ties&#8217;.\u00a0 This will allow you to play with several configurations without having to screw or glue.\u00a0 Ideally you&#8217;ll want the camera to revolve only around its &#8216;nodal point&#8217;.\u00a0 This is not usually easy to do, but luckily, most modern panorama stitching software are smart enough to handle reasonable nodal point offsets.\u00a0 To minimize the camera&#8217;s nodal offset, it is best to place the lens as close to the holder pivot mechanism as possible.\u00a0 This may mean that the camera has to be oriented upside down or sideways.\u00a0 No problem &#8211; any good panorama stitching software can detect and correct image rotations.<\/p>\n<p>By combining the two functions already designed above, you can now design a single application which iteratively moves the camera and writes high-quality images out to a sequential set of files in a designated output directory.\u00a0 The camera should pan and tilt to allow at least 20% overlap of each image with its neighbor&#8217;s.\u00a0 Upon capture termination, a metadata file can be written out to summarize how many pictures were captured, their capture times, orientations, and possibly the board&#8217;s GPS location.\u00a0 Once this application is up and functioning, you can add a Linux shell script to tar and compress the results on successful capture completion.\u00a0 You can even have the script upload the archive to another site via FTP, or to a SAMBA directory on a nearby laptop.\u00a0 It&#8217;s a pity that Dropbox support is minimal at this time for Linux.\u00a0\u00a0 Though the BeagleBoard could perform the stitching directly, it is best to simply have the small ARM based board collect the pictures, and do the stitching on a platform that can handle the computation and memory necessary to do this activity properly.\u00a0 In addition, you can have the BeagleBoard collect panoramas and queue their output to a destination computer where the stitching can be done in parallel.\u00a0 In fact, the panorama capture, transfer, and stitching activities can all be done in parallel.<\/p>\n<p>Along the way, you will find lots of &#8216;gotchas&#8217;.\u00a0 For example, as the pan\/tilt mechanism moves, the USB wire attached to the camera will often get caught on one of the other system components (e.g., maestro 12).\u00a0 You can configure the USB cable in a variety of ways to avoid this from happening.\u00a0 When you are done stitching the panorama, you may find that the images aren&#8217;t aligned with enough overlap to achieve the desired stitching.\u00a0 When you write the pan\/tilt stepping code, remember not bake hard coded values into the logic.\u00a0 You can do this by setting a system variable such as &#8216;overlap_percent&#8217; to control the stepping behavior.\u00a0 This is a bit harder than just using a constant controller stepping value because you will need to translate &#8216;overlap_percent&#8217; into a step size based on known camera specification parameters (e.g. FOV).\u00a0 The work will be worth it when you upgrade the system camera later to one which has different characteristics and parameters.<\/p>\n<p><a href=\"\/Blog\/wp-content\/uploads\/Beagle3.jpg\"><img decoding=\"async\" class=\"aligncenter\" src=\"\/Blog\/wp-content\/uploads\/Beagle3.jpg\" alt=\"Miniature BeagleBoard Panorama Capture System!\" width=\"540\" \/><\/a><\/p>\n<p>So, now you hook up your BeagleBoard, and you go to a room in your house, and start your collection application.\u00a0 The results are captured, transferred wirelessly to a computer nearby, and stitched without issue.\u00a0 Are you done?\u00a0 Not really, but we are starting to have fun &#8211; right?\u00a0 The problem is that wireless connections cannot be guaranteed wherever you go.\u00a0 That is, some indoor locations will not have WIFI, and others will not allow your device to connect to their Access Points.\u00a0 Even if you could connect wirelessly, you would still need to obtain the wireless parameters for each venue and communicate them somehow to the BeagleBoard for connection before the panorama collection process can begin.\u00a0 You could do this with an external keyboard\/mouse\/LCD panel, but that defeats the small and mobile aspects of this project.\u00a0 Another way is to use a mobile phone for hotspot tethering.\u00a0 This would be an easy way to guarantee a wireless connection in most places.\u00a0 Additionally, the hotspot parameters won&#8217;t change so the BeagleBoard can have a static wireless configuration.<\/p>\n<p>But, what if there is no data service to your mobile device at a location?\u00a0 Again, no problem.\u00a0 As a backup plan, your background upload queue daemon on the BeagleBoard can hold up till a hotspot connection is restored.\u00a0 And, what if the BeagleBoard storage is nearly filled?\u00a0 You can have the background queue daemon also monitor the local storage device (SD card) periodically, and blink an LED light on the BeagleBoard via the board&#8217;s GPIO when space is limited.\u00a0 If the operator sees the blinking LED, the panorama archives can be transferred directly to an external portable hard drive.\u00a0 The same queuing and status daemon can additionally poll for an external hard drive.\u00a0 If the drive becomes active, the outstanding queued items can be transferred to the external drive and then removed from the local queue.\u00a0 Once the transfer is complete, the blinking light can cease.<\/p>\n<p>BeagleBoard controlled lights can be used for more than just space notification.\u00a0 They can also be used to notify the operator that the device is ready, WIFI connection has been lost, or the battery is getting low.\u00a0 These are design elements that can be added iteratively over time.\u00a0 As the device is used in the field, feedback from operators will also drive new enhancements to the design.\u00a0 But, don&#8217;t try to do everything at once.\u00a0 Work on the parts separately and test them rigorously.\u00a0 It is also important not to minimize the importance of the component selection for your device.\u00a0 For example, a camera could be selected simply because of its low-power consumption and its reasonable MTBF.\u00a0 But, if it has poor resolution or low-light handling, the stitching may be impossible later.\u00a0 The best way to think of the field collection process is that it will only be done once.\u00a0 It may be feasible to return to a location for a subsequent capture, but it&#8217;s probably best to assume that the capture can only be done once due to expense, logistics, time constraints, or contractual agreements.<\/p>\n<p>The same panorama collection setup on the BeagleBoard can be used for other projects requiring similar configurations.\u00a0 For example, a WII Nunchuk controller can be used to pan\/tilt the camera &#8220;live&#8221; using it&#8217;s Bluetooth connection.\u00a0 The results are similar to security camera systems with operator control.\u00a0 Using a WIFI hotspot connection, it is naturally possible to extend such a system to one where the operator is situated remotely.  Such a system can also prompt a remote user of movement via web services or an email.\u00a0 If you think outside-the-box, there is no telling how far you can take it.<\/p>\n<p>Below is a short clip taken of the device I created during its capture operation very early in the development cycle.\u00a0 The setup is still crude here, but the camera functions well and yields a quite useable product.\u00a0 In later development stages, the mouse\/keyboard\/LCD are no longer needed, the device footprint is reduced significantly.<\/p>\n<div style=\"display: block; margin-left: auto; margin-right: auto;\" align=\"center\">\t<video id=\"wp_mep_1\" src=\"\/Blog\/Video\/BeagleBoard_Runthrough.mp4\" type=\"video\/mp4\" width=\"640\" height=\"480\" poster=\"\/Blog\/Video\/BeagleBoardProject.jpg\" controls=\"controls\" preload=\"true\"  >\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t<\/video>\r\n<script type=\"text\/javascript\">\r\njQuery(document).ready(function($) {\r\n\t$('#wp_mep_1').mediaelementplayer({\r\n\t\tm:1\r\n\t\t\r\n\t\t,features: ['playpause','current','progress','duration','volume','tracks','fullscreen']\r\n\t\t\r\n\t});\r\n});\r\n<\/script>\r\n<\/div>\n<p>The first example stitched panorama output from the device is shown below.\u00a0 It is only a 180 degree collection set, but the results were easily stitched and the detail present is quite acceptable (the original is quite a bit bigger).\u00a0 In later development stages, the capture is a full 360 degree collection, and the resolution and detail are further increased.\u00a0 Stay tuned for the next BLOG entry which will cover other ways to utilize and build upon the current design.<\/p>\n<p><a href=\"\/Blog\/wp-content\/uploads\/BeagleBoardExamplePano180Large.jpg\"><img decoding=\"async\" class=\"aligncenter\" src=\"\/Blog\/wp-content\/uploads\/BeagleBoardExamplePano180.jpg\" alt=\"Miniature BeagleBoard Panorama Capture System!\" \/><\/a><br \/>\n[whohit]-RASPBERRYPI-[\/whohit]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So Google didn&#8217;t hire you, but you still want to do cool things like engineer a miniature device to capture indoor 360 degree panoramas. Not to worry. The key to reaching this challenge lies in the art of breaking down goals into manageable pieces. You&#8217;ll need to build these pieces separately and then integrate. Finally, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[100,101,87,71,58,1],"tags":[133,113,109,102,103,106,111,47,105,107,112,104,108,110],"class_list":["post-411","post","type-post","status-publish","format-standard","hentry","category-beagleboard","category-pantilt","category-panorama-2","category-photography-passion","category-photography-workflow","category-uncategorized","tag-beagleboard","tag-c","tag-control","tag-embedded","tag-linux","tag-maestro","tag-pan","tag-panorama","tag-servo","tag-servocity","tag-tilt","tag-ubuntu","tag-usb","tag-wifi"],"_links":{"self":[{"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=411"}],"version-history":[{"count":63,"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/411\/revisions"}],"predecessor-version":[{"id":651,"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/411\/revisions\/651"}],"wp:attachment":[{"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/analyze3d.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}