<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://robotics.ninthyard.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://robotics.ninthyard.com/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-05-16T00:01:30+00:00</updated><id>https://robotics.ninthyard.com/feed.xml</id><title type="html">DMC Robotics</title><subtitle>Calvin is an open-hardware two-wheel self-balancing robot. This site is a working development log on the hardware, firmware, perception, planning, and control.</subtitle><author><name>Damon Cali</name></author><entry><title type="html">Engraving Plastic</title><link href="https://robotics.ninthyard.com/notes/2026/04/11/engraving-plastic/" rel="alternate" type="text/html" title="Engraving Plastic" /><published>2026-04-11T02:35:00+00:00</published><updated>2026-04-11T02:35:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/04/11/engraving-plastic</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/04/11/engraving-plastic/"><![CDATA[<p>I wanted to add some nice labels for the various switches and knobs that will find their way onto Calvin. Currently, that means 4 power switches — one for each motor (Sinister and Dexter), one for the Teensy (Instinctus), and one for the Jetson Orin Nano (Cogitator). I thought I’d give the Carvera another run and use an engraving bit on some engraving plastic (the stuff where you machine away the top layer to reveal a different color underneath).</p>

<p>I ran into a couple of problems. One is that getting Autodesk Fusion to make decent toolpaths for this is not easy or obvious. You have to do a lot of guessing and trial and error. The second is that the plastic will melt and gum up the bits easily, which I found out when cutting the holes. It takes a combination of light but decisive cuts with a single-flute end mill to get it done well. Over time the bit heats up, and the plastic doesn’t transfer heat well, so it melts. Long-running operations may have to be broken up.</p>

<p>The combination I found that worked for the engraving was to use a 15°, 0.2 mm tip D-bit with the Engraving operation, setting the Bottom Height in Fusion to −0.1 mm from the Top Height (the same depth as the modeled text). It’s also very finicky about the font. I had the best luck with Helvetica Bold at 2.5 mm text height. Strangely, Arial did not work well at all.</p>

<p>Eventually I got it right, and I think the plate came out well.</p>

<figure>
  
    <img src="/assets/images/label-plate.webp" alt="Engraved plastic label plates for Calvin&#39;s power switches" loading="lazy" decoding="async" width="1600" height="1013" />
  
  
    <figcaption>
      
      Engraved label plates for the power switches.
    </figcaption>
  
</figure>]]></content><author><name>Damon Cali</name></author><category term="mechanical" /><summary type="html"><![CDATA[I wanted to add some nice labels for the various switches and knobs that will find their way onto Calvin. Currently, that means 4 power switches — one for each motor (Sinister and Dexter), one for the Teensy (Instinctus), and one for the Jetson Orin Nano (Cogitator). I thought I’d give the Carvera another run and use an engraving bit on some engraving plastic (the stuff where you machine away the top layer to reveal a different color underneath).]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-engraving-plastic.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-engraving-plastic.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Chassis Parts</title><link href="https://robotics.ninthyard.com/notes/2026/04/08/chassis-parts/" rel="alternate" type="text/html" title="Chassis Parts" /><published>2026-04-08T22:16:00+00:00</published><updated>2026-04-08T22:16:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/04/08/chassis-parts</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/04/08/chassis-parts/"><![CDATA[<figure>
  
    <img src="/assets/images/chassis-cad.webp" alt="CAD render of Calvin&#39;s basic chassis design" loading="eager" decoding="async" width="1600" height="1600" />
  
  
    <figcaption>
      
      CAD render of Calvin's basic chassis.
    </figcaption>
  
</figure>

<p>Since the last update, I’ve received my 3.4 mm carbide drill bits. They work really well in the Carvera, although you have to do some tinkering to get the collars onto them, since you can’t pass a 3.4 mm bit through a 3.175 mm hole.</p>

<p>After a lot of learning and mistakes, I managed to machine the aluminum plates that hold the motors, as well as some small aluminum bearing retainers to keep the flanged bearings from falling out. The retainers could have been printed, but half the point of this project is intentionally overdoing things as a learning experience.</p>

<p>I’ve partially assembled the ODrive motors onto the plates. The fit is nice and tight, and they spin freely. If you look closely, you’ll see the gray magnet coupling attached to the back end of the shaft. That’s a resin print that holds and aligns the magnet needed for the ODrive encoder to work. It requires a precise fit, so I printed it with my resin printer. I could also have machined it out of brass or aluminum (something non-ferrous), but printing it was easier. I probably could have gotten away with just gluing the magnet to the end of the shaft, but I didn’t want to risk it in when doing it right is so easy.</p>

<figure>
  
    <img src="/assets/images/motor-plates.webp" alt="Partially assembled motor plates with ODrive motors mounted" loading="lazy" decoding="async" width="1800" height="1400" />
  
  
    <figcaption>
      
      Partially assembled motor plates with ODrive motors mounted.
    </figcaption>
  
</figure>

<p>The current goal is to completely assemble the chassis. Both motor plate assemblies and the printed frame pieces (top, bottom, front, and rear) are needed. The idea is to use printed frames with removable carbon fiber access panels to cover up Calvin’s internals. The frames need to fit the panels relatively precisely, so warping is a problem. And unfortunately, I had a lot of warping problems.</p>

<p>After a few tries with the usual tricks, I decided to try something new and ordered some PET-CF17 carbon fiber filament. I’ve never used it before, but it’s supposed to help. However, to use it, I needed a new hardened nozzle for my Prusa Core ONE printer. I’m still waiting on that, and since the motor plates are finished, I’m working on a few things I hadn’t planned to do until later.</p>

<p>One thing that’s already done—but will be in another post—is the label plates for the power switches on either side of the robot. I’m also working out how to machine the power and ground busses from C110 copper bar. I know I don’t need to make them so robust or precise, but it’s a good opportunity to try out the Carvera with a new material.</p>]]></content><author><name>Damon Cali</name></author><category term="mechanical" /><summary type="html"><![CDATA[CAD render of Calvin's basic chassis.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-chassis-parts.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-chassis-parts.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Printing Jigs</title><link href="https://robotics.ninthyard.com/notes/2026/03/14/printing-jigs/" rel="alternate" type="text/html" title="Printing Jigs" /><published>2026-03-14T13:14:00+00:00</published><updated>2026-03-14T13:14:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/14/printing-jigs</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/14/printing-jigs/"><![CDATA[<p>While I was waiting for drill bits, I decided to solve a problem that’s been bothering me for a while. The frame (made of 2020 aluminum extrusions) is slightly out of square. It wobbles when I place it on a flat surface, such as a granite countertop. This has been nagging at me because, in my experience, the extrusions are cut very precisely. Mechanical precision is important when you’re trying to get a robot not just to balance, but to balance <em>well</em>.</p>

<p>After a lot of thinking and tweaking, I came to the conclusion that I am the problem. To hold the extrusions together, I tapped the end holes with an M5 tap. That’s a good idea, except I did it too hastily—the threads were not quite straight. When you add up all the minor misalignments, you end up with a wobbly frame.</p>

<p>To fix this, I started over using some cast corner brackets I found on Amazon. I also decided to tap some holes in new extrusions for non-structural parts to be added later. This time, I printed jigs to keep the threads straight. I also printed another jig to drill access holes in the corner brackets.</p>

<figure>
  
    <img src="/assets/images/tapping-jig.webp" alt="3D-printed tapping jig keeps threads straight" loading="lazy" decoding="async" width="1600" height="2133" />
  
  
    <figcaption>
      
      A printed tapping jig keeps the M5 threads straight.
    </figcaption>
  
</figure>

<figure>
  
    <img src="/assets/images/drilling-jig.webp" alt="3D-printed jig for drilling clearance holes" loading="lazy" decoding="async" width="1600" height="2133" />
  
  
    <figcaption>
      
      A second jig for drilling clearance holes in the corner brackets.
    </figcaption>
  
</figure>]]></content><author><name>Damon Cali</name></author><category term="mechanical" /><summary type="html"><![CDATA[While I was waiting for drill bits, I decided to solve a problem that’s been bothering me for a while. The frame (made of 2020 aluminum extrusions) is slightly out of square. It wobbles when I place it on a flat surface, such as a granite countertop. This has been nagging at me because, in my experience, the extrusions are cut very precisely. Mechanical precision is important when you’re trying to get a robot not just to balance, but to balance well.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Cutting Metal</title><link href="https://robotics.ninthyard.com/notes/2026/03/10/cutting-metal/" rel="alternate" type="text/html" title="Cutting Metal" /><published>2026-03-10T17:24:00+00:00</published><updated>2026-03-10T17:24:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/10/cutting-metal</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/10/cutting-metal/"><![CDATA[<p>The Teensy 4.1 has arrived. I didn’t realize it had a USB micro connector, so now I’m waiting for a USB cable. In the meantime, I decided to finally put to use the Carvera CNC mill I bought almost a year ago. Calvin’s mechanical design uses 3D-printed PLA and ABS as much as possible, but there are a few parts that really ought to be aluminum — mainly the plates that mount the motors.</p>

<p>The motor plates have pockets for some 10 mm OD bearings that need to hit a pretty tight tolerance: ±0.001” on the diameter. I was a little concerned that such a small machine might not be able to hit that, but I’m happy to note that the Carvera is more than capable of that kind of precision. It does require careful setup, light passes, and a little bit of compensation in the NC code. The pockets were about 0.002” undersize, so adding negative 0.002” “stock to leave” brought them right to where they’re supposed to be. Once I sorted that out with a test part, I’m very happy with the results - the bearings are a tight slip fit. The next step is to machine the actual parts. I’m waiting on some drill bits for that, but they should be here soon.</p>

<figure>
  
    <img src="/assets/images/carvera-test-piece.webp" alt="Test piece used to dial in the Carvera CNC mill" loading="lazy" decoding="async" width="1600" height="987" />
  
  
    <figcaption>
      
      Test piece used to dial in the Carvera.
    </figcaption>
  
</figure>]]></content><author><name>Damon Cali</name></author><category term="mechanical" /><summary type="html"><![CDATA[The Teensy 4.1 has arrived. I didn’t realize it had a USB micro connector, so now I’m waiting for a USB cable. In the meantime, I decided to finally put to use the Carvera CNC mill I bought almost a year ago. Calvin’s mechanical design uses 3D-printed PLA and ABS as much as possible, but there are a few parts that really ought to be aluminum — mainly the plates that mount the motors.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-cutting-metal.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-cutting-metal.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Wireless Telemetry</title><link href="https://robotics.ninthyard.com/notes/2026/03/05/wireless-telemetry/" rel="alternate" type="text/html" title="Wireless Telemetry" /><published>2026-03-05T13:51:00+00:00</published><updated>2026-03-05T13:51:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/05/wireless-telemetry</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/05/wireless-telemetry/"><![CDATA[<p>In the last post, I got the communication between Cogitator and Explorator working, but with a couple of constraints:</p>

<ul>
  <li>The telemetry data was not being generated by Instinctus—it was just dummy data created inside Cogitator.</li>
  <li>Both Cogitator and Explorator were running on my Mac.</li>
</ul>

<p>Since then, I made a small step forward by installing Cogitator on the Jetson Orin Nano and running it inside the NVIDIA Docker container that provides access to the NVIDIA software stack and device hardware. I was able to connect to the Jetson from my Mac over Wi-Fi and stream dummy data to Explorator. Basically, the same thing I did before, but now the communication works between the two devices.</p>

<p>The final step in this communications chain is to get the data out of Instinctus, send it to the Jetson via serial, and then pass it through Cogitator to Explorator. I’m still waiting for the Teensy to arrive, so in the meantime I’ll work on refining Explorator and planning the next services to implement in Cogitator.</p>]]></content><author><name>Damon Cali</name></author><category term="cogitator" /><category term="explorator" /><summary type="html"><![CDATA[In the last post, I got the communication between Cogitator and Explorator working, but with a couple of constraints:]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Connecting the Pipes</title><link href="https://robotics.ninthyard.com/notes/2026/03/04/connecting-the-pipes/" rel="alternate" type="text/html" title="Connecting the Pipes" /><published>2026-03-04T00:15:00+00:00</published><updated>2026-03-04T00:15:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/04/connecting-the-pipes</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/04/connecting-the-pipes/"><![CDATA[<p>It’s going to take a week or so to get a Teensy 4.1 in, so work on Instinctus has stopped for a minute. Instead, I took some time to continue working out how data will flow from one system to the next. As a starting point, Instinctus will transmit ToF and IMU data to Cogitator over serial. Cogitator will take that data and make it available to Explorator over a WebSocket connection.</p>

<p>The Instinctus code will have to wait, but it will basically consist of a loop that reads the data and dumps it into a serial buffer on the Teensy. Nothing earth-shaking.</p>

<p>Cogitator is Python code written for the Jetson Orin Nano. It will be composed of several independent services coordinated by ZeroMQ. Initially, these services are:</p>

<ul>
  <li><strong>serial:</strong> This is the counterpart to the Instinctus serial connection. It takes data off the buffer and makes it available to subscribing services through a broker.</li>
  <li><strong>gateway:</strong> The gateway manages WebSocket connections and serves up data for Explorator to consume.</li>
  <li><strong>dummy:</strong> <code class="language-plaintext highlighter-rouge">dummy</code> is just a drop-in replacement for <code class="language-plaintext highlighter-rouge">serial</code> that generates fake data so I can incrementally build and test the system. For now, it’s what I’m using.</li>
</ul>

<p>There is also a <code class="language-plaintext highlighter-rouge">broker</code>- a dumb pipe that routes data from publishers to subscribers. Right now, that’s just <code class="language-plaintext highlighter-rouge">dummy</code> publishing and <code class="language-plaintext highlighter-rouge">gateway</code> subscribing.</p>

<p>Over on Explorator, a WebSocket connection is created and maintained. For now, this is all running on my Mac, so it’s just a local connection — no Jetson involved. Data is then put in a Pania store, and UI elements react to changes. The result is a real-time chart of the data being produced by dummy. Once Instinctus is up and running, the full path from Instinctus to Cogitator to Explorator will be complete.</p>

<figure>
  
    <img src="/assets/images/real-time-tof-data-chart.webp" alt="Real-time chart of simulated ToF data" loading="lazy" decoding="async" width="992" height="912" />
  
  
    <figcaption>
      
      Real-time chart of simulated ToF data.
    </figcaption>
  
</figure>]]></content><author><name>Damon Cali</name></author><category term="cogitator" /><category term="explorator" /><summary type="html"><![CDATA[It’s going to take a week or so to get a Teensy 4.1 in, so work on Instinctus has stopped for a minute. Instead, I took some time to continue working out how data will flow from one system to the next. As a starting point, Instinctus will transmit ToF and IMU data to Cogitator over serial. Cogitator will take that data and make it available to Explorator over a WebSocket connection.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">In the Beginning</title><link href="https://robotics.ninthyard.com/notes/2026/03/02/in-the-beginning/" rel="alternate" type="text/html" title="In the Beginning" /><published>2026-03-02T16:03:00+00:00</published><updated>2026-03-02T16:03:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/02/in-the-beginning</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/02/in-the-beginning/"><![CDATA[<p>I had completed quite a bit of the design before creating this site, but I want to start from scratch with the build log and work through the process step by step. First up is the basic frame design and the mounting bracket for the Jetson, two ToF sensors, and the balance IMU.</p>

<p>The design is pretty straightforward—the frame is made from 2020 aluminum extrusions held together with M4 screws. A 3D-printed bracket holds the Jetson and sensors, keeping the IMU (mounted on the bottom of the bracket, out of sight) as close to the center of the axle as possible. Shown here are the beginnings of the frame, with the bracket and sensors in place. The Jetson will be added later.</p>

<p>You can see in the photograph that the three sensors are connected with I2C cables, all of which will be on the same bus. The long wires are attached to the ToF sensors’ XSHUT pins, which are used to turn the sensors on and off and to set the I2C address on boot.</p>

<figure>
  
    <img src="/assets/images/frame-with-sensors-cad.webp" alt="Frame with sensors mounted" loading="lazy" decoding="async" width="1600" height="1383" />
  
  
    <figcaption>
      
      Frame with sensors mounted.
    </figcaption>
  
</figure>

<figure>
  
    <img src="/assets/images/frame-with-sensors-photo.webp" alt="Sensors daisy-chained on an I2C bus" loading="lazy" decoding="async" width="1600" height="1200" />
  
  
    <figcaption>
      
      Sensors daisy-chained on an I2C bus.
    </figcaption>
  
</figure>]]></content><author><name>Damon Cali</name></author><category term="mechanical" /><summary type="html"><![CDATA[I had completed quite a bit of the design before creating this site, but I want to start from scratch with the build log and work through the process step by step. First up is the basic frame design and the mounting bracket for the Jetson, two ToF sensors, and the balance IMU.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">RIP Arduino</title><link href="https://robotics.ninthyard.com/notes/2026/03/02/rip-arduino/" rel="alternate" type="text/html" title="RIP Arduino" /><published>2026-03-02T14:30:00+00:00</published><updated>2026-03-02T14:30:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/02/rip-arduino</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/02/rip-arduino/"><![CDATA[<p>Calvin’s Arduino GIGA R1 WiFi died. Last night, I burned my finger when I briefly touched the memory chip on the board—it was extremely hot. As best I can tell, that means the board is fried, even though it’s still working (for now). How this happened is a mystery. I could have accidentally shorted something, miswired it, or it might simply be defective. In any case, it’s toast.</p>

<p>This gives me an opportunity to change gears in the design. I was beginning to regret going with the GIGA for a couple of reasons. First, it’s expensive (~$70) and has far more capability than I need. I primarily chose it so I could use the GIGA Display Shield, and I liked the dual-core architecture. But as I’ve gotten further into the project, the display has become less compelling. It works, but it’s slow and doesn’t provide the experience I expected. I’ve also moved on to a much more robust remote monitoring system (Calvin Explorator), which makes the display significantly less useful.</p>

<p>So I’m ditching the Arduino and its display and switching to a Teensy 4.1. It’s cheaper, smaller, more than capable, and has all the features I need.</p>

<p>One downside is that I’ll need to add Teensy support to <code class="language-plaintext highlighter-rouge">grot</code>, and I’m a little concerned that <code class="language-plaintext highlighter-rouge">teensy_loader_cli</code> won’t work on macOS 26 (Homebrew says it will, but you never know—the official docs are quite old). But one way or another, I’ll get it working.</p>

<p>The other downside is that the Teensy uses a single-core architecture. I liked having basic/safety functions isolated on their own core, separate from less stable systems. But without the display, the M7 core was essentially just a pass-through to the Jetson. Two cores don’t really serve a useful purpose anymore. There are also techniques to minimize the impact of non-critical code on the critical loop.</p>

<p>This means I have to rewrite the entire event queue system. It’s not a huge issue — just more work to be done.</p>]]></content><author><name>Damon Cali</name></author><category term="instinctus" /><category term="hardware" /><summary type="html"><![CDATA[Calvin’s Arduino GIGA R1 WiFi died. Last night, I burned my finger when I briefly touched the memory chip on the board—it was extremely hot. As best I can tell, that means the board is fried, even though it’s still working (for now). How this happened is a mystery. I could have accidentally shorted something, miswired it, or it might simply be defective. In any case, it’s toast.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Event Queue</title><link href="https://robotics.ninthyard.com/notes/2026/03/01/the-event-queue/" rel="alternate" type="text/html" title="The Event Queue" /><published>2026-03-01T17:32:00+00:00</published><updated>2026-03-01T17:32:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/01/the-event-queue</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/01/the-event-queue/"><![CDATA[<p>I wanted an architecture that provided maximum isolation for the M4 core. If anything were to interrupt other systems, the M4 core should remain lean and reliable. However, we still need a way for other parts of the system to send information to the M4—things like navigation targets or emergency signals generated outside the M4. The best way to do this is to create an inter-core event queue (implemented in the InstinctusKit code, which contains everything shared by both cores).</p>

<p>The event queue allows either core to add events and either core to process them. The only way to communicate with the M4 is through the M7 using the event queue. This is possible because a small amount of RAM is accessible to both the M7 and M4. The details are dense, but long story short, careful memory management enables safe, atomic, non-blocking communication into and out of the M4.</p>

<p>So what are the events? There aren’t many right now, but that will change in the future. For now, the only implemented events are:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  EVENT_BALANCE_IMU_DATA   : Sends a stream of IMU data to the M7 core (each event is a single data point).
  EVENT_TOF_DATA           : Sends a stream of data from the two ToF sensors to the M7 core.
  EVENT_PROXIMITY_WARNING  : Broadcasts a warning to both cores that an object is too close.
  EVENT_EMERGENCY_STOP     : Broadcasts a warning to both cores that power will be shut down immediately.
</code></pre></div></div>

<p>Events are processed by the destination core as they are received. At the moment, the M4 primarily streams data to the M7, triggers a proximity warning if the ToF sensors detect something too close, and initiates an emergency stop if the tilt angle exceeds the safe threshold.</p>]]></content><author><name>Damon Cali</name></author><category term="instinctus" /><summary type="html"><![CDATA[I wanted an architecture that provided maximum isolation for the M4 core. If anything were to interrupt other systems, the M4 core should remain lean and reliable. However, we still need a way for other parts of the system to send information to the M4—things like navigation targets or emergency signals generated outside the M4. The best way to do this is to create an inter-core event queue (implemented in the InstinctusKit code, which contains everything shared by both cores).]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Nervous System</title><link href="https://robotics.ninthyard.com/notes/2026/03/01/the-nervous-system/" rel="alternate" type="text/html" title="The Nervous System" /><published>2026-03-01T17:28:00+00:00</published><updated>2026-03-01T17:28:00+00:00</updated><id>https://robotics.ninthyard.com/notes/2026/03/01/the-nervous-system</id><content type="html" xml:base="https://robotics.ninthyard.com/notes/2026/03/01/the-nervous-system/"><![CDATA[<p>Calvin’s “nervous system” is handled by the Arduino GIGA R1 WiFi board. The GIGA is a dual-core microcontroller (M4 and M7). Both cores run separate sketches but share access to the hardware.</p>

<p>The most fundamental functions—balancing, motor control, and basic safety (such as object collision detection)—run on the M4 core. The only hardware attached to the M4 is an IMU and two Time-of-Flight (ToF) sensors.</p>

<p>The IMU is used to balance Calvin and to detect collisions by monitoring spikes in accelerometer data.</p>

<p>The two ToF sensors detect obstacles. One faces forward, and the other faces rearward. Their purpose is to provide a reliable indication that something is in the way without having to rely on other, less dependable systems.</p>

<p>The M4’s code is designed to be simple, reliable, and isolated from the more complex (and occasionally finicky) systems running on the M7 core and the Jetson. If something else fails, the M4 should still be able to provide basic functionality.</p>]]></content><author><name>Damon Cali</name></author><category term="instinctus" /><summary type="html"><![CDATA[Calvin’s “nervous system” is handled by the Arduino GIGA R1 WiFi board. The GIGA is a dual-core microcontroller (M4 and M7). Both cores run separate sketches but share access to the hardware.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" /><media:content medium="image" url="https://robotics.ninthyard.com/assets/images/og-default.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>