<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>kieferbot | Blue Duck Valley Rd</title><link>https://juju.nz/michaelh/tags/kieferbot/</link><atom:link href="https://juju.nz/michaelh/tags/kieferbot/index.xml" rel="self" type="application/rss+xml"/><description>kieferbot</description><generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>en-us</language><copyright>© 2017-2025 Michael Hope</copyright><lastBuildDate>Sun, 19 Apr 2020 00:00:00 +0200</lastBuildDate><image><url>img/map[gravatar:%!s(bool=false) shape:circle]</url><title>kieferbot</title><link>https://juju.nz/michaelh/tags/kieferbot/</link></image><item><title>Tracking using a camera</title><link>https://juju.nz/michaelh/post/2020/tracking/</link><pubDate>Sun, 19 Apr 2020 00:00:00 +0200</pubDate><guid>https://juju.nz/michaelh/post/2020/tracking/</guid><description>&lt;p>Here&amp;rsquo;s Kieferbot being tracked through a camera:&lt;/p>
&lt;p>&lt;video controls src="tracking.mp4">&lt;/video>&lt;/p>
&lt;p>It took a few iterations but I settled on matching the colour of the
floor to create a floor mask, then
&lt;a href="https://docs.opencv.org/trunk/d4/d73/tutorial_py_contours_begin.html" target="_blank" rel="noopener">findCountours&lt;/a> to find the
contours as a tree, and then searching the children of the root
contours. As the bot is black, the children were matched against a
&amp;lsquo;black pixels&amp;rsquo; mask, and the contour with the most black pixels
picked.&lt;/p>
&lt;p>The camera is an Android phone running
&lt;a href="https://play.google.com/store/apps/details?id=com.pas.webcam&amp;amp;hl=en" target="_blank" rel="noopener">IP Webcam&lt;/a> and sharing
the back camera as MJPEG over HTTP over Wifi at 10 FPS. It could be
higher, but the laptop doing the image processing has trouble keeping
up with 30 FPS. The latency looks good - visually less than 200 ms.&lt;/p>
&lt;p>The tracking seems reliable. If the bot goes off the bottom of the
frame then other black areas are picked, but this can be detected by
checking for a jump in position.&lt;/p>
&lt;p>Next step is to integrate the camera position, phone sensors, and
wheel velocity to get a controllable position.&lt;/p></description></item><item><title>Self-contained and smoke</title><link>https://juju.nz/michaelh/post/2020/kiefer_pine/</link><pubDate>Sat, 11 Apr 2020 00:00:00 +0200</pubDate><guid>https://juju.nz/michaelh/post/2020/kiefer_pine/</guid><description>&lt;p>A day of highs and lows. Here&amp;rsquo;s Kieferbot still in
&lt;a href="https://en.wikipedia.org/wiki/Teleoperation" target="_blank" rel="noopener">teleop&lt;/a>
mode but now self contained:&lt;/p>
&lt;p>&lt;video controls src="self.m4v">&lt;/video>&lt;/p>
&lt;p>The
&lt;a href="https://wiki.pine64.org/index.php/PinePhone" target="_blank" rel="noopener">PinePhone&lt;/a> is taking commands from a PS4 DualShock
over Bluetooth using &lt;code>ds4drv&lt;/code> and sending them to the IO board over
serial. I experimented with a few transports:&lt;/p>
&lt;ul>
&lt;li>UDP over Wifi was fine, but the default ESP32 Wifi power mode added
random latency of up to 100 ms. Switching to &amp;lsquo;always on&amp;rsquo; mode by
modifying MicroPython fixed this.&lt;/li>
&lt;li>Bluetooth Low Energy worked for one-way communication to the IO
board, but there was lots of packet loss when using Bluetooth for
both the joystick and IO.&lt;/li>
&lt;/ul>
&lt;p>Inspired by
&lt;a href="https://github.com/firmata/protocol" target="_blank" rel="noopener">Firmata&lt;/a>, I settled on MIDI over serial. I
quite like the MIDI format for short messages. A frame starts with
the command followed by a command specific payload. The command has
the MSB set so it&amp;rsquo;s simple to frame.&lt;/p>
&lt;p>I also compiled
&lt;a href="http://wiki.ros.org/kinetic" target="_blank" rel="noopener">ROS Kinetic&lt;/a> for Debian Buster and created an IO node
that takes left and right velocity commands. There seems to be an
ordering issue with either the ESP32 PWM chip or the FIT0441
controller, where going from forward to reverse and vice-versa is
fine but the motor won&amp;rsquo;t start sometimes when going from zero.&lt;/p>
&lt;p>So plenty of highs, but the low was
&lt;a href="https://en.wikipedia.org/wiki/Magic_smoke" target="_blank" rel="noopener">releasing the smoke&lt;/a> - I&amp;rsquo;m
using a LiPo battery for the supply and something short-circuited when
unplugging the battery. It seems to have taken out the regulator and
the ESP32 flash.&lt;/p>
&lt;p>Next step is to re-make the IO board using an
&lt;a href="https://www.adafruit.com/product/3800" target="_blank" rel="noopener">ItsyBitsy M4&lt;/a>. It
also runs MicroPython so the IO software was easy to port. I&amp;rsquo;ve
ordered some Seeed
&lt;a href="https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0&amp;#43;-p-4426.html" target="_blank" rel="noopener">XIAO&lt;/a> boards - $5 gives you a MicroPython
compatible SAMD21 with 9 pins of IO which is enough for this project.&lt;/p>
&lt;p>This time I&amp;rsquo;ll secure the battery socket better and 3D print a
shield.&lt;/p></description></item><item><title>Teleop</title><link>https://juju.nz/michaelh/post/2020/kiefer_telop/</link><pubDate>Sun, 22 Mar 2020 00:00:00 +0200</pubDate><guid>https://juju.nz/michaelh/post/2020/kiefer_telop/</guid><description>&lt;p>As a winter project, I&amp;rsquo;m turning my
&lt;a href="https://wiki.pine64.org/index.php/PinePhone" target="_blank" rel="noopener">PinePhone&lt;/a> into an
indoor robot. The Pinephone has everything needed for a decent
stand-alone robot: plenty of CPU, a camera,
gyro/accelerometor/compass, display, and it can run Debian.&lt;/p>
&lt;p>Below is a video of the hardware in
&lt;a href="https://en.wikipedia.org/wiki/Teleoperation" target="_blank" rel="noopener">teleop&lt;/a> mode. A
&lt;a href="https://wiki.wemos.cc/products:lolin32:lolin32" target="_blank" rel="noopener">Lolin32&lt;/a>
&lt;a href="https://www.espressif.com/en/products/hardware/esp32/overview" target="_blank" rel="noopener">ESP32&lt;/a>
running
&lt;a href="https://micropython" target="_blank" rel="noopener">MicroPython&lt;/a> takes commands over
Bluetooth LE and sends PWM and direction signals to the
&lt;a href="https://wiki.dfrobot.com/FIT0441_Brushless_DC_Motor_with_Encoder_12V_159RPM" target="_blank" rel="noopener">FIT0441&lt;/a>
motors. The frame is 3D printed.&lt;/p>
&lt;p>&lt;video controls src="teleop.m4v">&lt;/video>&lt;/p>
&lt;p>Currently the phone is just a passenger. The next step is to get the
phone to communicate with the IO board.&lt;/p></description></item></channel></rss>