<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.4">Jekyll</generator><link href="https://bldrbts.me.uk/met-2019/feed.xml" rel="self" type="application/atom+xml" /><link href="https://bldrbts.me.uk/met-2019/" rel="alternate" type="text/html" /><updated>2019-08-29T14:50:18-05:00</updated><id>https://bldrbts.me.uk/met-2019/feed.xml</id><title type="html">M.E.T. 2019</title><subtitle>Mars Extraterrestrials team for Pi Wars 2019</subtitle><author><name>M.E.T.</name></author><entry><title type="html">After the Competition</title><link href="https://bldrbts.me.uk/met-2019/2019/04/10/competition.html" rel="alternate" type="text/html" title="After the Competition" /><published>2019-04-10T00:00:00-05:00</published><updated>2019-04-10T00:00:00-05:00</updated><id>https://bldrbts.me.uk/met-2019/2019/04/10/competition</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2019/04/10/competition.html">&lt;p&gt;The good news is: we at least attempted all challenges and Phantom survived (mostly). The bad news is: we did very badly.&lt;/p&gt;

&lt;p&gt;Here is how the “final” version of Phantom, our walker based on poorly understood alien technology, looked like (photos taken after the competition):&lt;/p&gt;

&lt;figure class=&quot;third&quot;&gt;

&lt;a href=&quot;/met-2019/assets/2019-04-10/phantom2.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/phantom2_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-04-10/phantom1.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/phantom1_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-04-10/phantom3.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/phantom3_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;

&lt;/figure&gt;

&lt;p&gt;Unfortunately, Phantom was far from finished. We had to cut a lot of features that we initially intended to have during the last few months, but that wasn’t enough: we couldn’t even finish the essentials in time. Our goals have proven to be a bit too ambitious, and by spending a lot of time on various details, some of which were probably not essential, we ended up in a situation where &lt;em&gt;everything&lt;/em&gt; was half- or almost finished, but &lt;em&gt;nothing&lt;/em&gt; ready. (“Second-system effect” maybe?)&lt;/p&gt;

&lt;p&gt;This led to last-minute assembly of the “final” version, including late-night re-printing of the chassis the day before to fix some sizing mistake, taking short-cuts where things didn’t quite fit together, like using Blu Tack – with a few minutes left at the end for testing and hacking on the software to at least make the basics work (the latter continuing even during the competition).&lt;/p&gt;

&lt;p&gt;We also had a major problem with our choice of motors that only became apparent very late – see the &lt;a href=&quot;/met-2019/2019/03/12/control-problems.html&quot;&gt;previous post&lt;/a&gt;. This meant a lot of time wasted, and at the end we had to fall back to the small micro metal gear motors we used earlier: these had just about enough power to drive reliably, but were very slow. Ideally, you should finalise the mechanical / locomotion / motor control part of the robot first, and build everything higher level or fancier on these already stable foundations. In our case, the seriousness of the lack of precise control at low speeds only became obvious when we tried to implement control for the autonomous challenges – so maybe it’s a chicken and egg problem: you don’t really know if your “foundation” is good enough until you actually use it for real…&lt;/p&gt;

&lt;p&gt;Despite all this, the overall journey was great fun, a lot of “crazy” experimenting with a huge amount of completely new things tried and learned – in no small part thanks to the awesome Pi Wars community! And even despite failing in literally every challenge, the final Sunday we’ve been waiting for a long time was amazing and we thoroughly enjoyed it!&lt;/p&gt;

&lt;p&gt;And now, here is a summary of how and what we did at each challenge – and most importantly, the lessons learned (or should be learned)!&lt;/p&gt;

&lt;h2 id=&quot;pi-noon-the-right-stuff&quot;&gt;Pi Noon: The Right Stuff&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/gearbox_weak_point.png&quot; alt=&quot;&quot; class=&quot;half-right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/met-2019/assets/2019-04-10/damage.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/damage_small.jpg&quot; alt=&quot;&quot; class=&quot;half-right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We got “destroyed” in the first few minutes: our opponent, a much heavier robot, hit us from the left and a critical part of a single 3D-printed gearbox/motor assembly that connects the big gearbox with the motor, snapped. This was a fatal blow: with a broken gearbox, we couldn’t move and there was a risk of dropping out of the rest of the competitions for the day.&lt;/p&gt;

&lt;p&gt;It wasn’t our opponent’s fault though: Pi Noon is supposed to be “non-destructive” but even if you’re not doing it intentionally, it’s inherently aggressive in the sense that you do need to drive at your opponent, and collisions are inevitable. If a heavy robot with a lot of motor power happens to hit sideways a weak or unprotected spot, damage is inevitable.&lt;/p&gt;

&lt;p&gt;We didn’t have any spare parts, but fortunately we did bring lots of sticky tape, even two different kinds! So we managed to fix the broken gearbox. There was nothing else apart from the tape, nothing rigid to support the weight, and to prevent the left side from collapsing. It was a little bit wobbly, but amazingly, the tape held throughout the whole day!&lt;/p&gt;

&lt;h3 id=&quot;analysis&quot;&gt;Analysis&lt;/h3&gt;

&lt;p&gt;The main issue is that the part that snapped is cleary too weak: those two horizontal bits were supporting the whole weight of the robot and were too thin.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Phantom was &lt;em&gt;not designed or even tested for Pi Noon&lt;/em&gt;, so the danger from this kind of collision wasn’t even considered.&lt;/li&gt;
  &lt;li&gt;The gearbox/motor assembly was actually a weaker, second version: the original design was for bigger motors, with wider and thicker struts. This second version was “Plan B”, designed hastily, “merging” parts of the original (holding a round motor) with a rectangluar holder for the small motors we had to revert to.&lt;/li&gt;
  &lt;li&gt;We should have done some stress-testing for the critical 3D-printed parts: nothing fancy, just testing it by hand to see how easy it is to break it would have helped!&lt;/li&gt;
  &lt;li&gt;We were planning to print and bring a spare gearbox complete with legs, just in case something breaks or fails during the day. Due to lack of time, this didn’t happen.&lt;/li&gt;
  &lt;li&gt;Sticky tape can be stronger than 3D-printed plastic!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;spirit-of-curiosity&quot;&gt;Spirit of Curiosity&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/met-2019/assets/2019-04-10/IMG_20190331_112554.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/IMG_20190331_112554_small.jpg&quot; alt=&quot;&quot; class=&quot;half-right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was quite a straightforward challenge – you pick up a sample and bring it back, right? The reality is, getting over the crater in the middle was very dangerous as we weren’t sure if Phantom would survive a fall onto its back. The only other option was to go around which was very time-consuming and also the robot only just fitted into the canyon around the large “hill”, and so it was difficult to maneuver through it. The small bumps and uneven details were also a problem as the robot got stuck on them on more than one occasion. We still managed to bring back &lt;em&gt;one&lt;/em&gt; piece of sample though!&lt;/p&gt;

&lt;h3 id=&quot;analysis-1&quot;&gt;Analysis&lt;/h3&gt;

&lt;p&gt;In theory, legs should be perfect for this terrain. Unfortunately, our motors didn’t have enough power. The legs were also quite small, as we wanted to keep the robot body as small as possible. Phantom was also very slow: even without getting stuck, we wouldn’t have been able to do many more round-trips in the allowed time.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We really need motors that are both more powerful and faster.&lt;/li&gt;
  &lt;li&gt;Making the legs a little bit bigger and/or changing the stride to lift the legs higher would definitely help here to avoid getting stuck.&lt;/li&gt;
  &lt;li&gt;Another problem (which we luckily didn’t encounter) was the chance of the sample falling out and having to go back to the pile again. To avoid this the robot should be quite stable and maybe it would have been nice to have added some sort of suspension.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-canyons-of-mars&quot;&gt;The Canyons of Mars&lt;/h2&gt;

&lt;p&gt;We didn’t have high hopes for this challenge. The “proper” code was not ready and all the testing was done the night before, for about 5 minutes. So we just relied on a very simple idea that we were experimenting with: a simple, generic “behaviour” to keep going forward and avoid obstacles – just based on distance sensors, without knowing anything about the layout of the maze, or taking into account orientation or anything else.&lt;/p&gt;

&lt;p&gt;The code is literally just a few lines. Here it is:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dist_sensor_angles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run_canyons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'dist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;                                           &lt;span class=&quot;c1&quot;&gt;# Return if distances not available yet
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'speed'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;                                   &lt;span class=&quot;c1&quot;&gt;# Drive at constant speed, forward (max. is 10)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;dist_vectors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist_sensor_angles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# Get the distances as vectors,
&lt;/span&gt;                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist_sensor_angles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;#   measured at ±90° (sides) and ±45° (front)
&lt;/span&gt;                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist_sensor_angles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;#   (and ignore the front sensor at 0°)
&lt;/span&gt;                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist_sensor_angles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dist_sum&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum_vectors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dist_vectors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;# Add up the above vectors
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'dist_sum'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist_sum&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'dir'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rad2deg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dist_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.8&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;# Turn towards dist_sum: the longest opening
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is how it looks in simulation, using the same exact code as above (the yellow “beam” is the &lt;code class=&quot;highlighter-rouge&quot;&gt;dist_sum&lt;/code&gt; vector):&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/canyons_sim.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/canyons_sim.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;(One interesting thing learned from the simulation: at first, we tried it with only the three sensors at the front – it was much harder, almost impossible to navigate through without hitting a wall or turning back. But adding the left and right 90° sensors made a very big improvement!)&lt;/p&gt;

&lt;p&gt;We didn’t win with this of course, but it worked surprisingly well: in our first try, we only needed one “rescue”, near the top left corner, and after that, our robot continued to the exit. On the second try, somewhere near the second bend, it turned back and found its way back to the entrance – taking a shortcut, which is completely reasonable if your “goal” is to escape, rather than to go through the maze!&lt;/p&gt;

&lt;h3 id=&quot;analysis-2&quot;&gt;Analysis&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;This “success” has proven that it was worth it to develop all the simulation tools, and that sometimes a very simple approach can work too.&lt;/li&gt;
  &lt;li&gt;With some more tweaks (e.g. something like disallowing 360° turns or backing off when getting too close to a wall and trying again), and a bit more real-life testing, this could have been made much more robust.&lt;/li&gt;
  &lt;li&gt;And of course: Phantom was slow – we need more speed!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;space-invaders&quot;&gt;Space Invaders&lt;/h2&gt;

&lt;p&gt;No surprises here. The shooter attachment simply didn’t make it: we had an idea, but this was one of the things that were completely left out at the end, due to lack of time. So we simply tried to nudge the balls but Phantom was too slow. The tiny motors we ended up using were just enough to slowly and carefully roll the balls over the white line, but not much further.&lt;/p&gt;

&lt;h2 id=&quot;the-apollo-13-obstacle-course&quot;&gt;The Apollo 13 Obstacle Course&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/met-2019/assets/2019-04-10/IMG_20190331_151526.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/IMG_20190331_151526_small.jpg&quot; alt=&quot;&quot; class=&quot;half-right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This challenge was fairly straightforward apart from the treadmill which was very frightening. We ended up skipping it because Phantom didn’t have any thing protecting it should it fall over and flip. The rest of the course wasn’t too difficult – the problem was time. The robot was simply very slow and so we only managed to do one lap and were over the time limit.&lt;/p&gt;

&lt;h3 id=&quot;analysis-3&quot;&gt;Analysis&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The Oyumaru thermo plastic ’feet’ (a silicone-like material that melts easily in hot water and can then be formed by hand) were really useful in this challenge for gripping onto slopes (and just generally not falling over). The feet worked very well and didn’t come off (unlike last year’s wheels).&lt;/li&gt;
  &lt;li&gt;There were no problems with controllability. But we had an idea that we didn’t get around to implement: “absolute” directions for remote control: by using the compass (9DoF sensor) the joystick could be used to point to absolute directions: so instead of turning left relative to the current heading of the robot, you could point “left” to the “left” of the course. So it wouldn’t matter where you stand – as it’s quite difficult to move around the course and adjust your sense of direction when standing behind or in front of the robot.&lt;/li&gt;
  &lt;li&gt;We really didn’t have any practice driving before – even if the robot isn’t particularly fast, this would have helped, and some testing with any kind of mock course would have made us more confident!&lt;/li&gt;
  &lt;li&gt;We need more speed…&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-hubble-telescope-nebula-challenge&quot;&gt;The Hubble Telescope Nebula Challenge&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/met-2019/assets/2019-04-10/colour_calibration.png&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-04-10/colour_calibration_small.png&quot; alt=&quot;&quot; class=&quot;half-right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was a perfect example of &lt;em&gt;trying to do a bit of everything but finishing nothing&lt;/em&gt;: last year we didn’t attempt this challenge at all. This time, we spent quite a lot of time on perfecting the colour calibration, developing the tools for it, etc. The code was &lt;em&gt;almost&lt;/em&gt; ready, the colour recognition worked perfectly, but the whole thing was left unfinished at the end, because of all the other tasks that seemed more critical, like fixing fundamental motor control problems.&lt;/p&gt;

&lt;p&gt;So at the end we just attempted to use the “easy” method of trying to visit all corners, only using distances from walls (ToF sensors) and orientation (9DoF sensor) without using the camera at all. The code was put together in the pit room, with no real-world testing. It &lt;em&gt;could&lt;/em&gt; have worked, but unfortunately it didn’t: some parameters (speed, minimum corner distances) were not set correctly, so Phantom ended up wandering around the course, looking very confused.&lt;/p&gt;

&lt;h3 id=&quot;analysis-4&quot;&gt;Analysis&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Better prioritisation earlier could have helped: maybe giving up preparing for one of the simpler challenges completely, we could have saved some time to finish the work for this and at least have a good chance of doing this one correctly.&lt;/li&gt;
  &lt;li&gt;Brian Corteil’s Robot Club at the Cambridge Makespace was a great opportunity to test things in the real courses, under the same conditions as at the competition: but because we were always behind schedule, we mostly missed this!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;blast-off-the-straight-ish-line-speed-test&quot;&gt;Blast Off: the Straight-ish Line Speed Test&lt;/h2&gt;

&lt;p&gt;This is really the easiest of the autonomous challenges: as long as you have reliable sensors, there shouldn’t be a problem… We were relying on our ToF distance sensors and an even simpler algorithm than for Canyons of Mars. Again, we didn’t do much testing and wasn’t expecting to be fast, but maybe with some oscillations between the walls this should have worked just fine.&lt;/p&gt;

&lt;p&gt;Unfortunately, one of the many leg joints on the right got stuck a little, so the right side could barely move. This resulted in the robot turning right in the beginning, and hitting the wall. The code was just pushing the motor to maximum power, trying to reach the set speed, but of course it wasn’t prepared for this fault. (Generally, in this case the right thing would be to reduce power to the other side to match the side that’s blocked, and keep going in the desired direction, just much slower.)&lt;/p&gt;

&lt;h3 id=&quot;analysis-5&quot;&gt;Analysis&lt;/h3&gt;

&lt;p&gt;It took a long time and a lot of experimenting to design the joints. Some of the challenges were: keeping the size small, ensuring the joints can rotate smoothly, but still making the joints as rigid as possible, reducing sideways motion to avoid too much wobble. The final design used M2 screws covered with PTFE tubing inside the joints, secured at the end with lock nuts press-fitted into the plastic parts (and with also some thread locker fluid). This seemed to work really well, and we didn’t see much of this issue of getting stuck before. However:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assembling the legs was quite a long process and required manually cutting the PTFE tubes to exact sizes, and each screw had to be tightened “just right”. After assembly it was difficult to tell whether something was too tight or too loose, without actually trying to drive the robot and looking at the movement and checking the motor power for each side to see any differences.&lt;/li&gt;
  &lt;li&gt;The final version of the gearboxes and legs were assembled the day before, so these didn’t have much testing. It’s really odd that we only encountered this problem in the &lt;em&gt;last challenge&lt;/em&gt; in probably the easiest situation and haven’t seen any issues before during the whole day! But this proves the unreliability of the current design / assembly process.&lt;/li&gt;
  &lt;li&gt;We need to improve the design of the joints to ensure we have smooth movement, without relying on manual adjustments. Maybe switching to ball bearings – at least on some of the joints – would help, and would also reduce sideways movement (and wobble).&lt;/li&gt;
  &lt;li&gt;The failure to drive straight also highlighted an issue with the software: even if it doesn’t have to be complicated, all software driving the robot should be much more robust to be able to deal with failures or degraded functionality: this probably needs a different mindset, to consider every possibility, all the &lt;em&gt;what ifs&lt;/em&gt; and to fill in all those possible &lt;code class=&quot;highlighter-rouge&quot;&gt;else if&lt;/code&gt; branches!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is clearly a lot to keep us busy to fix all the problems we know of and finish everything properly for next time – the question is: will we do it or will we jump on to the next crazy idea and start from scratch again…?&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">The good news is: we at least attempted all challenges and Phantom survived (mostly). The bad news is: we did very badly.</summary></entry><entry><title type="html">Motor Control Problems</title><link href="https://bldrbts.me.uk/met-2019/2019/03/12/control-problems.html" rel="alternate" type="text/html" title="Motor Control Problems" /><published>2019-03-12T00:00:00-05:00</published><updated>2019-03-12T00:00:00-05:00</updated><id>https://bldrbts.me.uk/met-2019/2019/03/12/control-problems</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2019/03/12/control-problems.html">&lt;p&gt;In Pi Wars, there are a lot of puzzles and problems to solve. Some are hard, some are easier, but they are all fun, an opportunity to learn, experiment, do something crazy – that’s the whole point! But there is always one (or two!) completely new problem that turns up totally unexpected, usually at the worst possible time, and messes up all your plans. The famous &lt;em&gt;unknown unknowns…&lt;/em&gt; These are usually not much fun.&lt;/p&gt;

&lt;p&gt;Looks like we’ve run into one of these again.&lt;/p&gt;

&lt;p&gt;When we started experimenting with our first prototype, we used small N20 micro metal gear motors. They were slow, but had enough power to drive the small prototype. The movement looked good, including the ability to turn around in place: the legs worked as expected – a little bit wobbly maybe, but nothing too bad.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/motors.jpg&quot; alt=&quot;&quot; class=&quot;half-right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then we switched to bigger, more powerful, 600RPM motors for Phantom (the “real” robot): the goal was to make it run much faster, while still having enough torque at low speed. This was never tested properly, but everything seemed to be fine. Controlling the motors manually at low speed was harder: they need a “kick” to start, then you need to cut back the power to keep them going slower. So Phantom always appeared to be too excited or nervous, moving a bit wildly. The idea was to add speed sensors and a PID loop to control the speed, and we assumed this would “just work” and we’d get the best of both worlds: precise (good enough) control at low speeds, but also not going embarrassingly slowly in the Blast Off challenge.&lt;/p&gt;

&lt;p&gt;After a lot of hard work adding the speed sensors and implementing the PID control, adding a new GUI, etc. the unexpected problem appeared: &lt;em&gt;it was simply impossible to tune the PID parameters to get reasonable control!&lt;/em&gt; Controlling the speed on a “test bench” was OK: after some tuning we could see on the graph the motor power jumping up, followed by the the “measured RPM” value rising, and after just a bit of oscillation, nicely following the set speed. Adding some extra friction made the power rise again, while the measured RPM was still following the set value.&lt;/p&gt;

&lt;p&gt;On the ground it looked worse: starting to move in a straight line at low speed is not perfect, but at least it steadies after a few seconds.&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/phantom_straight.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/phantom_straight.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;Here is how a similar straight line start looks like on the graph: Some oscillations at the beginning, but not too bad – still, a bit slow to start in reality. Green: set RPM (constant 120), yellow: measured RPM, red: motor power.&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/straight_pid.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/straight_pid.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;Turning in place slowly is really bad though. There is probably too much slippage and sudden changes as legs get some traction, then slip or get blocked a bit, then move freely again… The motors don’t seem to have enough torque at low speed to keep moving, so the PID ends up driving the power up and down. The end result is that we can actually turn – much better than trying the same by manually controlling power – but the movement is very jerky.&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/phantom_circle.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/phantom_circle.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;Again, a similar turn on the graph: lots of oscillations (the compass in the lower right corner also shows how uneven the movement is). Also, there is a very clear difference between left (outer) and right (inner) legs.&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/circle_pid.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/circle_pid.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;It’s not clear how to fix this… There isn’t enough time to find better motors. One option is to just accept this and stop trying to go slowly, just keep running and stopping. But that’s a risky strategy. We can try changing the gear ratio in our “gearbox”, but there really isn’t much room for making big changes – not without a major redesign.&lt;/p&gt;

&lt;p&gt;By comparison, here is how the old prototype behaves with the micro metal gear motors (just directly connected to power, no control):&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/spider.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-12/spider.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;Looks much nicer! So another option could be to ditch the new fast motors, and go back to these tiny ones, hoping they will be enough for a bigger robot. But then it means this is about our top speed (the only speed really – it’s either going slow, or not at all). Our third option is a crazy idea, but that’s still a secret…&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">In Pi Wars, there are a lot of puzzles and problems to solve. Some are hard, some are easier, but they are all fun, an opportunity to learn, experiment, do something crazy – that’s the whole point! But there is always one (or two!) completely new problem that turns up totally unexpected, usually at the worst possible time, and messes up all your plans. The famous unknown unknowns… These are usually not much fun.</summary></entry><entry><title type="html">Speed Sensors and PCBs</title><link href="https://bldrbts.me.uk/met-2019/2019/03/06/ir-sensors-pcbs.html" rel="alternate" type="text/html" title="Speed Sensors and PCBs" /><published>2019-03-06T00:00:00-06:00</published><updated>2019-03-06T00:00:00-06:00</updated><id>https://bldrbts.me.uk/met-2019/2019/03/06/ir-sensors-pcbs</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2019/03/06/ir-sensors-pcbs.html">&lt;p&gt;Among the many things we wanted to improve in our robot design since last year, these two are probably the most important:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Add “proper” speed control:&lt;/strong&gt; don’t just control motor power and assume the resulting speed will always be proportional. With speed sensors and a feedback loop to adjust the power continuously, we can make the motors actually run at a given speed. This should lead to more precise and easier control (both manual and autonomous), being able to go slower even if the motors don’t have a lot of torque, going uphill or downhill at a constant speed, etc.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Make better and more integrated circuit boards:&lt;/strong&gt; last year’s robot used out-of-the box modules and chunks of perfboards and bundles of wires with bulky connectors to connect them all. Replacing at least some of these with “real” custom PCBs not only would make it much more &lt;em&gt;beautiful&lt;/em&gt;, but should also make everything smaller – which is especially important now that we have more components.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;ir-sensors-to-measure-speed&quot;&gt;IR Sensors to Measure Speed&lt;/h2&gt;

&lt;figure class=&quot;half&quot;&gt;
    &lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/encoder_wheel.jpg&quot; /&gt;
    &lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/sensor_gearbox.jpg&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;We are using a reflective infrared sensor (ITR8307) that is looking at an encoder disc with black and white stripes, inside the gearbox. The encoder disc is just a piece of paper glued to the center gear driven by the motor. An improvised hole provides a window for the sensor to peek inside. If we measure how long it takes for one stripe to pass in front of the sensor, we can calculate speed (RPM). Knowing the actual speed can enable better control of the motors and also to implement dead reckoning. We are only detecting speed, without direction, to keep things simple. (We want to avoid sudden changes in direction anyway, and the motors are not that fast, so assuming we’re always going the correct way may be safe.)&lt;/p&gt;

&lt;p&gt;The initial testing on a breadboard looked promising. (Who said that a breadboard makes it quick and easy to connecting things?! It’s a mess!)&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/ir_sensor_test.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/ir_sensor_test.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/comparator_sch.png&quot; alt=&quot;&quot; class=&quot;third-right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But it became obvious that the raw input from the sensor is very noisy and that the sensor needs to be very close to the surface of the disc to get reliable results. The main reason for this is that we’re treating the signal as digital input and want to only see either black or white – but the sensor doesn’t quite work like that: the voltage for a “high” signal obviously depends on the amount of light reflected, which is affected by the distance.&lt;/p&gt;

&lt;p&gt;One solution might be to read the voltage as an analog value and do thresholding in software. This method is probably more useful for things like line followers. What we would prefer is a hardware solution that turns the noisy analog singal into a clean digital one, which can easily be read by a microcontroller with an external interrupt.&lt;/p&gt;

&lt;p&gt;Some more research and experimenting resulted in a circuit which uses a comparator (LM339) with feedback. This produces a nice “black and white” digital output. A very good explanation of the basics can be found &lt;a href=&quot;http://www.ermicro.com/blog/?p=1578&quot;&gt;in this blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/testing.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Putting this circuit aside for now, let’s have a look at how the “final” version of the sensors look like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/ir_sensor_sch_brd.png&quot; alt=&quot;&quot; class=&quot;third-right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The sensors are mounted on small PCBs with a couple of resistors. The M.E.T. lab has a sophisticated process to make these, using the well-known DIY toner-transfer and vinegar-based etching methods:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Print the traces (mirrored) with a laser printer on a backing sheet for self-adhesive labels.&lt;/li&gt;
  &lt;li&gt;With a hot iron, transfer this image to the copper surface of the PCB (temperature and pressure is precisely controlled: just press it hard and remove it before things start to burn).&lt;/li&gt;
  &lt;li&gt;Pour some water into a small plastic container and add some acetic acid, rocket fuel (hydrogen peroxide) and table salt (using a very exact and secret ratio).&lt;/li&gt;
  &lt;li&gt;Watch it bubbling and add more salt as needed.&lt;/li&gt;
  &lt;li&gt;Take it out before all the copper disappears.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process is not always entirely reliable, but this time we were lucky and got a very nice result. (It looks a bit messy on the third image, but this is only because of the uneven surface of the manually tinned traces and the less than ideal lighting. The copper traces are actually perfect.)&lt;/p&gt;

&lt;figure class=&quot;third&quot;&gt;

&lt;a href=&quot;/met-2019/assets/2019-03-06/sensor_pcb1.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/sensor_pcb1_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-03-06/sensor_pcb2.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/sensor_pcb2_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-03-06/sensor_pcb3.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/sensor_pcb3_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;

&lt;/figure&gt;

&lt;h2 id=&quot;controlling-motor-power&quot;&gt;Controlling Motor Power&lt;/h2&gt;

&lt;p&gt;To control motor power, we need two things: something to generate a PWM signal and a motor driver that uses that signal to switch the higher current/voltage for the motors.&lt;/p&gt;

&lt;p&gt;The Pi can generate PWM so we could use that directly, but we are using a microcontroller for all the low-level real-time tasks. The PWM output will also depend on the continuous speed measurements, which are especially time-critical, so it makes sense to do both on a microcontroller, leaving only the high-level, non-real time control logic to the Pi.&lt;/p&gt;

&lt;p&gt;Last year we had to control four DC motors and five servos, and used an ATmega328 microcontroller, so the number of pins and available PWM outputs were a bit limited. This is why we added another component, a PCA9685 breakout board (a dedicated I&lt;sup&gt;2&lt;/sup&gt;C 16-channel PWM controller). For motor drivers, we used two DRV8833 2-channel motor driver boards. The assembly of all these was the &lt;a href=&quot;https://pdenes.github.io/met/2018/04/29/no-more-prototyping.html&quot;&gt;ACF-MAS (Actuator Controller For Motors And Servos)&lt;/a&gt;. It worked great, it was really easy to use, but it was all a bit bulky.&lt;/p&gt;

&lt;p&gt;This year we only have two DC motors so far: these can be controlled by only two PWM channels, so this doesn’t really require a dedicated component. Still, it seems like a good idea to use a proven solution with a lot of room for adding more motors (we have a few secret plans…) – and we always need a bit of over-engineering!&lt;/p&gt;

&lt;p&gt;Introducing &lt;strong&gt;MOC-SSIU&lt;/strong&gt; – the &lt;strong&gt;MO&lt;/strong&gt;tor &lt;strong&gt;C&lt;/strong&gt;ontrol and &lt;strong&gt;S&lt;/strong&gt;peed &lt;strong&gt;S&lt;/strong&gt;ignal &lt;strong&gt;I&lt;/strong&gt;ntegrator &lt;strong&gt;U&lt;/strong&gt;nit:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a PCA9685 I&lt;sup&gt;2&lt;/sup&gt;C 16-channel PWM controller chip&lt;/li&gt;
  &lt;li&gt;three 2-channel DRV8833 motor controller boards&lt;/li&gt;
  &lt;li&gt;an LM339 comparator to handle speed sensor signals&lt;/li&gt;
  &lt;li&gt;connectors for up to six DC motors (and their corresponding sensors)&lt;/li&gt;
  &lt;li&gt;a connector to the microcontroller for I&lt;sup&gt;2&lt;/sup&gt;C and sensor output (a 1.25mm pitch JST SMD connector that looks much better than the usual big pin headers and Dupont connectors)&lt;/li&gt;
  &lt;li&gt;power connector pins at the bottom (this will sit on top of &lt;a href=&quot;/met-2019/2018/11/19/power.html&quot;&gt;P-CAMS-2&lt;/a&gt;, the power board)&lt;/li&gt;
  &lt;li&gt;some “spare” connectors and extra pins for any future ad-hoc extensions, just in case&lt;/li&gt;
  &lt;li&gt;all this on a shiny new “professional” PCB!&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;half&quot;&gt;

&lt;a href=&quot;/met-2019/assets/2019-03-06/moc-ssiu-sch.png&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/moc-ssiu-sch_small.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-03-06/moc-ssiu-brd.png&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/moc-ssiu-brd.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;

&lt;/figure&gt;

&lt;p&gt;The Eagle files for this – and also for the IR sensor boards – can be found in our &lt;a href=&quot;https://gitlab.com/marsextraterrestrials/phantom&quot;&gt;GitLab repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We didn’t trust our own PCB-making process with this, so we ordered the boards (minimum order is five, so we have plenty of spares…) from &lt;a href=&quot;https://jlcpcb.com/&quot;&gt;JLCPCB&lt;/a&gt; – and they turned out perfect!&lt;/p&gt;

&lt;p&gt;Soldering the SMD components wasn’t too hard, although that PCA9685 chip is tiny! But solder paste (or surface tension?) is magical!&lt;/p&gt;

&lt;figure class=&quot;third&quot;&gt;

&lt;a href=&quot;/met-2019/assets/2019-03-06/new_pcbs.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/new_pcbs_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-03-06/pcb_half_pop.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/pcb_half_pop_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/met-2019/assets/2019-03-06/pcb_ready.jpg&quot;&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/pcb_ready_small.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;

&lt;/figure&gt;

&lt;p&gt;After populating one half of the new board, here is how the first test looked like. Unfortunately this meant disassembling almost everything. The “main” board also needs some rewiring to be able to connect it, we need to find a way to properly attach the sensors (probably printing a new cover for the gearboxes), and most importantly, the code on the microcontroller needs to be updated to actually implement speed control! But more on all this in another post…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-03-06/pcb_alive.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">Among the many things we wanted to improve in our robot design since last year, these two are probably the most important:</summary></entry><entry><title type="html">Remote Control</title><link href="https://bldrbts.me.uk/met-2019/2019/01/28/remote-control.html" rel="alternate" type="text/html" title="Remote Control" /><published>2019-01-28T00:00:00-06:00</published><updated>2019-01-28T00:00:00-06:00</updated><id>https://bldrbts.me.uk/met-2019/2019/01/28/remote-control</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2019/01/28/remote-control.html">&lt;p&gt;Finally, an update with some walking, running and spinning! We have a long way to go, but at least we have basic remote control working.&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/drive.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/drive.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;h3 id=&quot;from-joystick-to-motors&quot;&gt;From Joystick to Motors&lt;/h3&gt;

&lt;p&gt;Our robot uses a very alien mechanism to move but it has simple differential steering: one motor on each side drives the legs forwards or backwards, so the robot turns by applying more or less torque on one side – and it can also turn in place by running the motors in opposite directions. This should be straightforward to control with a game controller joystick. But how does this actually work?&lt;/p&gt;

&lt;p&gt;We don’t have encoders in the motors yet, so we can’t measure and control speed, all we can do for now is simply vary the motor power (PWM). The game controller gives us the position of the joystick as (x,y) coordinates within [–1, 1]. We need to somehow translate this to motor power (let’s say between –10 and 10) to be applied to left and right respectively.&lt;/p&gt;

&lt;p&gt;Some examples: driving full speed forwards – and turning right half speed (only the left motor is moving):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/jlr1.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/met-2019/assets/2019-01-28/jlr2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;…and going backwards full speed while turning slightly left – and finally, turning right in place, full speed:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/jlr5.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/met-2019/assets/2019-01-28/jlr3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are simple methods to do this directly and to make the joystick control feel “natural”, like this &lt;a href=&quot;https://github.com/ApproxEng/approxeng.input/blob/master/scripts/camjamedukit3.py#L107&quot;&gt;example for the &lt;code class=&quot;highlighter-rouge&quot;&gt;approxeng.input&lt;/code&gt; library&lt;/a&gt;. However, when the human driver is replaced by a program to drive the robot autonomously, we don’t want to deal with joystick coordinates. It would be much more natural to make the program produce some &lt;em&gt;desired speed&lt;/em&gt; and &lt;em&gt;turn direction&lt;/em&gt; values instead. So we’ve added this intermediate representation too. Instead of going from joystick to motors directly, we first interpret the joystick input as speed and direction, and then convert that to motor speeds: &lt;code class=&quot;highlighter-rouge&quot;&gt;(x, y)&lt;/code&gt; → &lt;code class=&quot;highlighter-rouge&quot;&gt;(speed, direction)&lt;/code&gt; → &lt;code class=&quot;highlighter-rouge&quot;&gt;(left, right)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the first step, we consider &lt;code class=&quot;highlighter-rouge&quot;&gt;(x, y)&lt;/code&gt; as a vector, take its length as speed and its angle as turn direction. Pointing upwards is 0°, maximum turn left and right is –90° and 90°. If the vector points down, we negate the speed.&lt;/p&gt;

&lt;p&gt;Using the same examples as above, this is what we want:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/jsd1.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/met-2019/assets/2019-01-28/jsd2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/jsd5.png&quot; alt=&quot;&quot; /&gt; &lt;img src=&quot;/met-2019/assets/2019-01-28/jsd3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There is one annoying problem with the joystick input however: the joystick actually moves inside a square, not a circle! So moving diagonally we’d get vectors longer than 1 – and different speeds depending on the angle, which is bad. We need to map square coordinates to a circle with this formula:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x → x * sqrt(1.0 - y * y / 2.0)
y → y * sqrt(1.0 - x * x / 2.0)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/circle.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(For more background and explanation, see &lt;a href=&quot;https://stackoverflow.com/questions/1621831/how-can-i-convert-coordinates-on-a-square-to-coordinates-on-a-circle&quot;&gt;this question on Stack Overflow&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;So the next step is to convert the corrected &lt;code class=&quot;highlighter-rouge&quot;&gt;(x,y)&lt;/code&gt; from above to &lt;code class=&quot;highlighter-rouge&quot;&gt;(speed,dir)&lt;/code&gt; – where speed is in &lt;code class=&quot;highlighter-rouge&quot;&gt;[-10,10]&lt;/code&gt; and angle in &lt;code class=&quot;highlighter-rouge&quot;&gt;[-90,90]&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cart2pol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# cart2pol: convert Cartesian to polar
&lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rad2deg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# np.rad2deg: convert radians to degrees
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;180&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Finally, to get left and right motor power from &lt;code class=&quot;highlighter-rouge&quot;&gt;(speed, dir)&lt;/code&gt;: we start by setting the desired speed to both motors, then reduce one side based on the turn angle:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;diff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;100.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;diff&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;diff&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The final result:&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/control.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-01-28/control.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;The complete code (and some more) for the above calculations can be found here: &lt;a href=&quot;https://gitlab.com/marsextraterrestrials/control_logic&quot;&gt;gitlab.com/marsextraterrestrials/control_logic&lt;/a&gt;&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">Finally, an update with some walking, running and spinning! We have a long way to go, but at least we have basic remote control working.</summary></entry><entry><title type="html">New Motors, New Legs, New Everything!</title><link href="https://bldrbts.me.uk/met-2019/2019/01/19/new-everything.html" rel="alternate" type="text/html" title="New Motors, New Legs, New Everything!" /><published>2019-01-19T00:00:00-06:00</published><updated>2019-01-19T00:00:00-06:00</updated><id>https://bldrbts.me.uk/met-2019/2019/01/19/new-everything</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2019/01/19/new-everything.html">&lt;p&gt;Here is the next stage in the evolution of our alien robot:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/DSC_0307.thumb.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;new-legs-and-gearboxes&quot;&gt;New legs and gearboxes&lt;/h3&gt;

&lt;p&gt;After an unreasonably long time spent on the design and a lot of experimentation on linkages, we’ve finally made our own leg mechanism. It uses the &lt;a href=&quot;https://en.wikipedia.org/wiki/Klann_linkage&quot;&gt;Klann linkage&lt;/a&gt;. Observing how our original toy kit based prototype worked (uses the same mechanism) and especially the resources on the &lt;a href=&quot;https://www.diywalkers.com/&quot;&gt;DIY Walkers&lt;/a&gt; website were an enormous help.&lt;/p&gt;

&lt;p&gt;A byproduct of all this work is &lt;a href=&quot;https://gitlab.com/paldenes/morescad&quot;&gt;“morescad”, a collection of some OpenSCAD utilities&lt;/a&gt;, including a module to help making linkages like this.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/DSC_0311.thumb.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The total number of parts for the two gearboxes and the eight legs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;50 individual 3D-printed parts&lt;/li&gt;
  &lt;li&gt;58 screws&lt;/li&gt;
  &lt;li&gt;2 axle sleeves (to connect the motor to the center gear)&lt;/li&gt;
  &lt;li&gt;4 hexagonal axles (for the two crank gears)&lt;/li&gt;
  &lt;li&gt;4 ball bearings&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;half&quot;&gt;
    &lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/gearbox1.png&quot; /&gt;
    &lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/gearbox3.png&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/gearbox2.png&quot; alt=&quot;&quot; class=&quot;third-right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The joints have press-fit self locking nuts and M2 screws, covered with small PTFE tubes (the kind used for 3D printer extruders) to reduce friction. The crank joints (blue bits above/below the gears on the picture) have a hole to insert a nut to hold a set screw connecting to the hexagonal shaft. We also use Loctite threadlocker glue on some of the screws – thanks to Brian C. for the suggestion! (We hope this will prevent us from losing legs like we did with wheels last year due to connections becoming loose.) The two crank gears are connected to the bottom part of the gearbox with ball bearings (transparent gray disc on the picture).&lt;/p&gt;

&lt;p&gt;The feet are not finished yet: we need to find something better than the rubber grommets added temporarily for now.&lt;/p&gt;

&lt;div class=&quot;cf&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;motors&quot;&gt;Motors&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/motors.jpg&quot; alt=&quot;&quot; class=&quot;third-right&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The new motors are 6V “600RPM Mini Metal Gearbox” motors from Ebay, hopefully with a good balance between speed and torque. They are much bigger than the N20 “Micro Metal Gearbox” ones we used earlier and last year. They are not very powerful, but the aim is to keep everything as small and light as possible. The stall current we measured was about 1.5A, and moving the legs freely takes about 2-300mA, so hopefully the tiny DRV8833 motor driver board (same as we used last year) will be able to handle this.&lt;/p&gt;

&lt;div class=&quot;cf&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;p-cams-2-rev-2&quot;&gt;P-CAMS-2 Rev. 2&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/met-2019/2018/11/19/power.html&quot;&gt;P-CAMS-2&lt;/a&gt; (Power Conversion And Management System 2) has also been updated: the previous version used a XL6009 buck-boost module, but some testing with the new motors has shown that it’s performance is not &lt;em&gt;quite&lt;/em&gt; like as advertised: its max. input current is supposed to be 3A, but set to 6V output with ~8V input, it shuts down immediately if the load reaches 1A at the output. This could be due to some obviously missing components on the board…&lt;/p&gt;

&lt;p&gt;So this has now been replaced by an XL4015 buck converter module, that’s slightly more reliable: when stalling a motor and reaching 1.5A (wires getting hot), its output drops to about 5V but it doesn’t shut down. This should be good enough…&lt;/p&gt;

&lt;p&gt;Another update is the addition of an AMS1117 3.3V LDO – so that we won’t need to use the Pi’s or the microcontroller’s built-in 3.3V regulator to power all the sensors and additional electronics.&lt;/p&gt;

&lt;h3 id=&quot;new-motorsensor-control-board&quot;&gt;New motor/sensor control board&lt;/h3&gt;

&lt;p&gt;This is another new part: a microcontroller board to control the motors and read the distance sensors. Previously we used a PCA9685 board to generate PWM, but this new board will probably replace that and will take care of controlling all DC motors and servos and will also handle the distance sensors. The board is a “Blue Pill” with an STM32F103C8 microcontroller – but more on all this later, in another post!&lt;/p&gt;

&lt;h3 id=&quot;frame-and-sensors&quot;&gt;Frame and sensors&lt;/h3&gt;

&lt;p&gt;So far we don’t have a complete body for the robot, only a very simple frame to hold the two gearboxes together and to support the various PCBs. This new frame and temporary layout should be enough to test all the components, both the existing ones and some new we’re planning to add later, and to refine movement and control. The ToF distance sensor array at the front is “borrowed” from our previous robot.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2019-12-19/DSC_0309.thumb.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But can it walk…? Or run…? Find out in the next post!&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">Here is the next stage in the evolution of our alien robot.</summary></entry><entry><title type="html">Power</title><link href="https://bldrbts.me.uk/met-2019/2018/11/19/power.html" rel="alternate" type="text/html" title="Power" /><published>2018-11-19T00:00:00-06:00</published><updated>2018-11-19T00:00:00-06:00</updated><id>https://bldrbts.me.uk/met-2019/2018/11/19/power</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2018/11/19/power.html">&lt;h2 id=&quot;pm-2-and-p-cams-2&quot;&gt;PM-2 and P-CAMS-2&lt;/h2&gt;

&lt;p&gt;In our &lt;a href=&quot;https://pdenes.github.io/met/2018/04/29/no-more-prototyping.html&quot;&gt;previous robot&lt;/a&gt;, in the 2018 Pi Wars, we used separate batteries for the electronics (one 18650 with a boost converter) and the motors (two 18650s in series with a buck converter). This was an easy and reliable solution to avoid any interference from electrical noise generated by DC motors. But it’s not very efficient: the batteries will not discharge at the same rate – and just two would probably provide enough total capacity anyway. This time we want to reduce the weight and also save some space. So here are the second versions of our modules:&lt;/p&gt;

&lt;figure class=&quot;half&quot;&gt;
    &lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-19/pm-2.jpg&quot; /&gt;
    &lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-19/p-cams-2.jpg&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;PM-2&lt;/strong&gt; (Power Module 2) is essentially a battery holder for two 18650 batteries in series with a protection circuit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P-CAMS-2&lt;/strong&gt; (Power Conversion And Management System 2) consists of two DC converters: one to provide 5V for the electronics, and another to give 6V to DC motors and servos. It also has a voltage divider to provide a usable input for battery voltage monitoring. The circuit is very simple:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-19/p-cams-2-sch.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;motor-noise&quot;&gt;Motor Noise!&lt;/h2&gt;

&lt;p&gt;After making a prototype of P-CAMS-2 on a perfboard, a quick test showed that everything worked fine: Pi Zero running, motors moving. For PWM, we’re using a PCA9685 I&lt;sup&gt;2&lt;/sup&gt;C module: this can control up to 16 motors or servos. It can only use a single frequency, so we’re using 60Hz, as the servos can’t really use something much higher, but this has worked well enough for the DC motors too.&lt;/p&gt;

&lt;p&gt;Turning the motors full on and off, driving forwards and backwards was OK. But when we tried varying the speed, I&lt;sup&gt;2&lt;/sup&gt;C suddenly started to fail: I/O errors after a few seconds, all the time. We did have 100n capacitors across the motor terminals, and also bigger electrolytics before each DC converter as buffers, but this was clearly not enough!&lt;/p&gt;

&lt;p&gt;Apollo 11 could land on the Moon, &lt;a href=&quot;https://en.wikipedia.org/wiki/Apollo_11#Lunar_descent&quot;&gt;despite a hardware problem that caused some scary 1201 and 1202 alarms.&lt;/a&gt; But instead of crashing, the software recovered, letting the humans ignore the errors and just carry on!&lt;/p&gt;

&lt;p&gt;So there is nothing to worry about, we can fix this in software, like this:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# ...Read inputs etc., then drive: set pwm via I2C...
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;OSError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Don't panic, it's only an error...
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# Just ignore and continue, but keep a count so that we can display this 
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# on some fancy control panel later or maybe even plot a chart...
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;err_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But maybe there is a better solution… Getting lots of errors in a reproducible way &lt;em&gt;now&lt;/em&gt; is actually a great opportunity! It means we can investigate the cause, try to change things one by one and see what has an effect on the errors! Much better than having a potential problem lurking somewhere undetected, only to come up later, randomly and unexpectedly!&lt;/p&gt;

&lt;p&gt;We experimented with adding capacitors to try and filter out the noise: many variations with different values, caps before or after the DC converters, and/or caps closer to the electronics, more caps near the motor driver, caps on the motor terminals, connected to the motor casing, with or without grounding the casing, etc. And we tested each combination, running the motors on low speed for a few minutes and checking the I&lt;sup&gt;2&lt;/sup&gt;C error rate. Some combinations looked promising at first, but none of them provided any major improvement or pointed towards the right direction.&lt;/p&gt;

&lt;p&gt;At the end it looked a bit ridiculous…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-19/caps.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We’ve done some research and found quite a lot of useful information:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://electronics.stackexchange.com/questions/153628/reduction-of-dc-motor-noise&quot;&gt;EE StackExchange: Reduction of DC motor noise&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.pololu.com/docs/0J15/9&quot;&gt;Pololu: Dealing with Motor Noise&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://andybrown.me.uk/2015/07/24/usb-filtering/&quot;&gt;Andy’s Workshop: Filtering the 5V USB power supply line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, thanks to a brilliant suggestion from &lt;a href=&quot;https://blog.usedbytes.com/&quot;&gt;Brian&lt;/a&gt;, we had a winning solution:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ferrite bead on the power leads to the electronics, right before the connection to the Pi!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-19/ferrite_bead.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Other combinations (adding the ferrite bead &lt;em&gt;before&lt;/em&gt; the DC converter or putting it further away from the connection) didn’t help or only slightly reduced the error rate. So it appears the positioning is very important, even with relatively short wires.&lt;/p&gt;

&lt;p&gt;After this &lt;em&gt;small step&lt;/em&gt; towards better and cleaner power, we hope we can work on something more creative and less frustrating next time!&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">In our previous robot, in the 2018 Pi Wars, we used separate batteries for the electronics. This was an easy and reliable solution to avoid any interference from electrical noise generated by DC motors. But it’s not very efficient: the batteries will not discharge at the same rate – and just two would probably provide enough total capacity anyway. This time we want to reduce the weight and also save some space.</summary></entry><entry><title type="html">First Steps (Literally)</title><link href="https://bldrbts.me.uk/met-2019/2018/11/12/first-steps.html" rel="alternate" type="text/html" title="First Steps (Literally)" /><published>2018-11-12T00:00:00-06:00</published><updated>2018-11-12T00:00:00-06:00</updated><id>https://bldrbts.me.uk/met-2019/2018/11/12/first-steps</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2018/11/12/first-steps.html">&lt;p&gt;The story of our new robot (Phantom) starts with a prototype: we are trying to validate our idea first, by using parts from a toy robot spider kit.&lt;/p&gt;

&lt;p&gt;On the 13th of October, we went to the Robot Club at Cambridge Makespace to start building our robot. First,
we built a very simple (but not that bad looking) walking robot (only legs + motors + battery, no control).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-10/simple.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-10/video1.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-10/video1.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;Then came the hard part: the boards which were unfortunately necessary, were (naturally) just the wrong size and shape to go with the rest of the structure.&lt;/p&gt;

&lt;p&gt;But that wasn’t the harderst part – no, it was having to take apart the beautiful design and replace it with a jumbled mess of wires:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-10/construction.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But now at least it could be a) programmed and b) inspected by a dog:&lt;/p&gt;

&lt;p&gt;
&lt;video controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-10/video2.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-10/video2.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;/p&gt;

&lt;p&gt;We tried out several methods of turning and we found that turning on the spot by moving the opposite banks of legs in the opposite direction to each other 
was possible.&lt;/p&gt;

&lt;p&gt;So even though our robot looks like some bizarre walking tower, it can walk and be programmed – what more could you want?&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">The story of our new robot (Phantom) starts with a prototype: we are trying to validate our idea first, by using parts from a toy robot spider kit.</summary></entry><entry><title type="html">Coming soon…</title><link href="https://bldrbts.me.uk/met-2019/2018/11/04/coming-soon.html" rel="alternate" type="text/html" title="Coming soon…" /><published>2018-11-04T00:00:00-05:00</published><updated>2018-11-04T00:00:00-05:00</updated><id>https://bldrbts.me.uk/met-2019/2018/11/04/coming-soon</id><content type="html" xml:base="https://bldrbts.me.uk/met-2019/2018/11/04/coming-soon.html">&lt;p&gt;On the 1st of October, an alien visitor landed on planet Earth.&lt;/p&gt;

&lt;p&gt;The alien was a Martian meteorite which had been travelling through space for many months before reaching planet Earth. Such landings where fairly common, it was what was inside that was unique.&lt;/p&gt;

&lt;p&gt;Two hours after the meteorite had landed, M.E.T. was on the scene. The meteorite was unearthed and taken into a mobile laboratory. Slowly, the shell of the object was removed and it became clear that it would have to be transferred to the main lab. Inside the shell was solid water – already gold to the scientists but inside was something even more extraordinary – a black object, blurred by the ice was glowing a deep, hypnotising purple…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-04/meteorite_1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;5 hours later, the sample was safely put into the main laboratory of the M.E.T. Complex. The world’s leading scientists examined it and it baffled even them. Once the ice had been safely melted and stored in a sterile container to be studied later, the object inside was revealed. It was clear that this was no terrestrial machine – it was almost like a living creature, only not – it was clearly artificial. It was a robot spider, and it seemed to be powered by a strange orb, now glowing a deep green…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://bldrbts.me.uk/met-2019/assets/2018-11-04/meteorite_2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</content><author><name>M.E.T.</name></author><summary type="html">On the 1st of October, an alien visitor landed on planet Earth.</summary></entry></feed>