The Ryan D. Lewis FeedPosts, projects, and other content from Ryan.2022-09-06T21:36:13Zhttps://ryandlewis.devRyan D. Lewispublic+feed@ryandlewis.devHow to Call a Service from a ROS2 Launch File2022-09-03T00:00:00Zhttps://ryandlewis.dev/posts/callserviceinros2launch/<p>This one is pretty straight forward, but took me a non-trivial amount of searching to find for myself. To call a ros2 service from a ros2 launch file, add the following to your launch file (see <a href="https://docs.ros.org/en/humble/Tutorials/Intermediate/Launch/Creating-Launch-Files.html">the official docs</a> for more on launch files):</p>
<pre><code class="language-python">from launch.substitutions import FindExecutable
from launch.actions import ExecuteProcess
...
ld.add_action(
ExecuteProcess(
cmd=[[
FindExecutable(name='ros2'),
" service call ",
"/namespace/service_to_call ",
"example_msgs/srv/ExampleMsg ",
'"{param_1: True, param_2: 0.0}"',
]],
shell=True
)
)
</code></pre>
<p>Note the following:</p>
<ul>
<li><code>ld</code> here is a variable containing an instance of <code>LaunchDescription</code></li>
<li><code>/namespace/service_to_call</code> is replaced with the service you're looking to call (don't forget any appropriate namespaces) and can be found with <code>ros2 service list</code></li>
<li><code>example_msgs/srv/ExampleMsg</code> is the message type used by that service, which you can get with <code>ros2 service info /namespace/service_to_call</code></li>
<li><code>"{param_1: True, param_2: 0.0}"</code> is the dictionary defining the message data. To find the parameters you need to set, you may need to consult the <code>.srv</code> file or documentation.</li>
</ul>
<p>Don't forget to include the <code>shell=True</code> argument, as the command will fail with a confusing "File not found" error without it.</p>
The Bandoleers Session 0272022-06-25T00:00:00Zhttps://ryandlewis.dev/posts/ttrpg/thebandoleers027/<h2 id="dm's-log%3A-supplemental...session-027" tabindex="-1">DM's Log: Supplemental...Session 027</h2>
<p><em>Date: 2022-06-01</em></p>
<h3 id="party%3A-the-bandoleers" tabindex="-1">Party: The Bandoleers</h3>
<ul>
<li>Kilomir, Minotaur Wild-Magic Barbarian</li>
<li>Faegwyn Suithrasas, High Elf School of Evocation Wizard</li>
<li>Ollie, Tiefling Way of the Long Death Monk</li>
<li>Mick Nichols, Rock Gnome Assassin Rogue
<ul>
<li>Accompanied by his trusty sidekick/mount, a Giant Duck named Lumpy</li>
</ul>
</li>
<li>Melisende, Cleric of Aelys and temporary Retainer accompanying the party</li>
</ul>
<h3 id="session-027-recap" tabindex="-1">Session 027 Recap</h3>
<p>We pick up at the beginning of the session exactly where we left off: immediately after the party fended off 12 hungry zombies and their Wight leader in the middle of the night. Though mostly unscathed, the party opted to finish their rest, and slept in.</p>
<p>Before resuming their journey, they searched the Zombie's corpses<a class="Footnotes__ref" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers027/#1-note" id="1-ref" aria-describedby="footnotes-label" role="doc-noteref"><sup title="Though they forgot the Wight, who had all the interesting stuff on him.">1</sup></a>, before deciding to hide them far enough off the side of the road that they wouldn't be seen. They then set off to make the final day's trek to the keep. Along the way, they came across an abandoned camp, complete with weapons and armor, presumably from the zombified guards.</p>
<p>Arriving at their destination at dusk, they prudently opted to make camp a safe distance away rather than approaching the keep at night. In the morning, Mick rode Lumpy up to survey their destination. He discovered the keep was dark, silent, and utterly absent of any sign of life, with the gate standing wide open and seemingly unprotected. Mick returned to the group with this news, and they concocted a plan: hide the wagon, approach on foot, sneak around back, and have Lumpy fly a rope attached to a grappling hook up to the top of the keep.</p>
<p>And so, a few good stealth rolls later, the party found themselves on the roof of the castle, inching down a dark staircase into the top floor of the keep. They poked around in a large dining area, noting the old food on the central table and investigating a couple statues around the perimeter of the room that Faegwyn determined were probably former Knights of the Westerwatch. Meanwhile, Mick got to work picking a locked door on one side of the room, and Kilomir kept a lookout.</p>
<p>Unfortunately, a very low perception roll meant that Kilomir was keeping an eye out for threats coming from <em>outside</em> the room, and failed to notice the 5 <a href="https://www.dndbeyond.com/monsters/1680917-boneless">Boneless</a> (undead remains lacking their skeletons) slithering out from beneath the large dining table in the center of the room.</p>
<p>The ambush led to a short but pitched battle, with the party successfully defeating the Boneless, though not before Mick was engulfed by one of the "Undead Murder Blankets" and nearly smothered to death. But Kilomir's <em>Longsword of the Forgotten Paladin</em>, with its extra Radiant Damage against Undead, Faegwyn's punishing Scorching Rays, and Ollie's onslaught of fists made quick work of their foes. The Party emerged from the fight a little battered, a little bruised, but ready to press deeper into the Westerwatch.</p>
<h2 id="dm's-post-mortem" tabindex="-1">DM's Post Mortem</h2>
<p>Okay, so two things stuck out to me about this session.</p>
<p>First, if you give one of your players a flying mount, assume they will use it for unconventional approaches to entering dungeons. I had a whole thing planned with a closing portcullis trap, which I've been itching to try out and was going to use with the entrance to the keep, and it was completely defanged just by them deciding to do an aerial insertion. Plus, now they're going through my encounter design backwards. Ah well.</p>
<p>Second, if you have a campaign that will heavily feature a certain type of enemy, don't give the low-level players a weapon that does <strong>2d10 magical bonus damage</strong> against enemies of that type, <em>especially</em> if those enemies often have weaknesses to said type. Or at least, equally distribute that among the party. Otherwise you'll find yourself in a situation where one character consistently outpaces the rest of the party in ways that are hard to balance around. Obvious in retrospect, but I don't think I really considered how much extra damage 2d10 is on <em>every attack</em>.</p>
<p>That's all for this post! Life's been a bit hectic recently (that's why this post is almost a month late), so I've got a small backlog of sessions to post about, so stay tuned for those!</p>
<footer role="doc-endnotes" class="Footnotes">
<h2 id="footnotes-label" class="Footnotes__title">Footnotes</h2>
<ol class="Footnotes__list"><li id="1-note" class="Footnotes__list-item" role="doc-endnote">Though they forgot the Wight, who had all the interesting stuff on him. <a class="Footnotes__back-link" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers027/#1-ref" aria-label="Back to reference 1" role="doc-backlink">↩</a></li></ol>
</footer>
The Bandoleers Session 0262022-05-18T00:00:00Zhttps://ryandlewis.dev/posts/ttrpg/thebandoleers026/<h2 id="dm's-log%3A-supplemental...session-026" tabindex="-1">DM's Log: Supplemental...Session 026</h2>
<p><em>Date: 2022-05-12</em></p>
<h3 id="party%3A-the-bandoleers" tabindex="-1">Party: The Bandoleers</h3>
<ul>
<li>Kilomir, Minotaur Wild-Magic Barbarian
<ul>
<li>The muscle of the group</li>
<li>Trying to learn how to craft Dragonborn Plate Armor</li>
</ul>
</li>
<li>Faegwyn Suithrasas, High Elf School of Evocation Wizard
<ul>
<li>Resident grumpy old man</li>
<li>Trying, with varying degrees of success, to expand the Wagonline business that he inherited after the unfortunate death of the previous proprietor at the vicious claws of a flock of cockatrice</li>
</ul>
</li>
<li>Ollie, Tiefling Way of the Long Death Monk
<ul>
<li>Mandatory party Edgelord</li>
<li>Has the unique ability to see and speak with the Gods of Corithynn</li>
</ul>
</li>
<li>Mick Nichols, Rock Gnome Assassin Rogue
<ul>
<li>Accompanied by his trusty sidekick/mount, a Giant Duck named Lumpy</li>
</ul>
</li>
</ul>
<h3 id="session-026-recap" tabindex="-1">Session 026 Recap</h3>
<p>In this session, The Bandoleers began their 3-day journey to the Westerwatch, a small keep nestled in the mountains west of the city of Dmittlock <a class="Footnotes__ref" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#1-note" id="1-ref" aria-describedby="footnotes-label" role="doc-noteref"><sup title="The city the party has been calling home for the majority of the campaign.">1</sup></a> that recently stopped sending reports. They were joined by a cleric, Melisende, of the local deity Aelys.<a class="Footnotes__ref" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#2-note" id="2-ref" aria-describedby="footnotes-label" role="doc-noteref"><sup title="They had requested Melisende's presence as part of their deal to look into the problem (plague outbreaks have been cropping up in the region, so the party wanted to have a healer on hand).">2</sup></a></p>
<p>The route to the Westerwatch is along a fairly well-traveled and "safe" road, and so their first day of travel passed without incident. As nightfall approached, they reached a small hamlet, where they decided to try and find a place to stay. And so they made the acquaintance of an old one-legged Rock Gnome named Igden Umbodoben, who was sitting on his porch and enjoying the fresh air.</p>
<p>After some pleasantries, Igden graciously agreed to put the party up in his barn for the evening for a crisp 5 silver. He also answered some questions about their route and destination (including telling them that a patrol of 12 towns guard had passed through on their way to the keep recently, and not yet returned).</p>
<p>The party's resident Gnome, Mick, also had a private sidebar with Igden, connecting over the fact that they were both veterans of a recent civil war in their home city, Quarriton. There was an awkward verbal dance where they both tried to figure out which side the other fought on, until eventually Igden asked directly and it was revealed they were both Partisans.</p>
<p>After an evening's rest safely in the barn, the second day of the journey brought them out of the dense forest surrounding Dmittlock. Now they found themselves journeying across grasslands and sloping hills which I described to the players as having "Big Iowa Energy". And, just like driving across Iowa, this day of travel passed without anything of note occurring.</p>
<p>With no civilization in sight this time at the end of the day, the party decided to take their wagon off the side of the road ("31 feet", per Kilomir's player's request). At this point, the party has learned to keep a watch, and so Ollie was dutifully patrolling around the wagon when he heard ominous moaning coming from down the road.</p>
<p>Peering out into the darkness with his Tiefling Dark Vision, Ollie was able to detect a small group of figures shambling up the road. After waiting a beat to see what they did and realizing that they were getting closer and closer, he decided to wake the others. Unfortunately, his attempt to do so quietly was foiled when he rolled in the single digits on a Stealth check, and as a result was given away by a <em>very</em> squeaky hinge on the wagon's door.<a class="Footnotes__ref" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#3-note" id="3-ref" aria-describedby="footnotes-label" role="doc-noteref"><sup title="At least this had the benefit of waking the rest of the party.">3</sup></a></p>
<p>As soon as the figures heard Ollie's racket, they froze. The party gathered and readied themselves, and, as the unidentified group began moving again, Faegwyn's sharp elvish eyes (and high perception roll) immediately identified the shuffling gait of wretched Undead. With a cry to alert the others, initiative was rolled as the Zombies charged in!<a class="Footnotes__ref" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#4-note" id="4-ref" aria-describedby="footnotes-label" role="doc-noteref"><sup title="'Charge' is relative, zombie's speed being what it is.">4</sup></a></p>
<p>The battle was chaotic but not necessarily difficult for the party. Ollie, Mick, and Kilomir charged to the fore, while Melisende and Faegwyn stayed back by the wagon. As it transpired, the <em>12 zombies</em> were joined by a Wight, who hung back and attempted (mostly unsuccessfully) to pepper Faegwyn with his longbow. The frontliners were able to clean up the Zombies without too much damage (Kilomir and Ollie came out entirely unscathed), and then chased down and dispatched the Wight when it attempted to flee.</p>
<p>And that's where we'll pick up next session!</p>
<h2 id="dm's-post-mortem" tabindex="-1">DM's Post Mortem</h2>
<p>Alright, so this session was...interesting...to try and run, because I made the mistake of trying to do it while sick.<a class="Footnotes__ref" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#5-note" id="5-ref" aria-describedby="footnotes-label" role="doc-noteref"><sup title="Some sort of respiratory bug. Tests say not COVID, but who can say at this point. Either way, we play over discord, so no players were at risk of IRL plague from the session.">5</sup></a> This meant that the session 1.) was shorter than I'd hoped, 2.) took me longer to prepare than usual, and 3.) was probably not my best work. I was determined to run, regardless of how miserable I felt, because scheduling is hard and it had already been awhile since our previous session and I didn't want to postpone again. But by the end of the night I was practically a zombie myself, and as soon as the Wight's HP hit 0 I was out.</p>
<p>But I did still get the opportunity to try some stuff I've been wanting to work in to the campaign, so let's talk about those things.</p>
<h3 id="on-melisende-and-retainers" tabindex="-1">On Melisende and Retainers</h3>
<p>There are many ways to run an NPC who's tagging along with a party of PCs.</p>
<ol>
<li>Roll up a PC and run them yourself (often frowned upon)</li>
<li>Make a stat block and run them as another NPC (more work for the DM, action economy in shambles)</li>
<li>The Companion Rules from <em>Tasha's Cauldron of Everything</em> (haven't tried them yet)</li>
<li>MCDM's Retainers <--This is the one I went with</li>
</ol>
<p>I've had MCDM's <em><a href="https://shop.mcdmproductions.com/products/strongholds-followers-hardcover-pdf">Strongholds and Followers</a></em> for awhile now, but hadn't gotten a chance to use the Retainer system introduced in it just yet. This system provides an easy way to give your PCs loyal companions which the DM roleplays, but the player runs in combat. The system is suppose to enable competent, helpful, and easy to run companions who don't steal the show from the main characters: the PCs.</p>
<p>As it just so happens, MCDM just recently released the kickstarter for their next book, <em><a href="https://www.kickstarter.com/projects/mattcolville/mcdm-monster-book">Flee, Mortals!</a></em>, and with it a <a href="https://files.mcdmproductions.com/FleeMortals/FleeMortalsPreview.pdf">26-page PDF preview</a>. And that preview included some updated Retainer rules (most notably replacing a somewhat clunky health level system from the original), so I decided to give that a shot. I used a "Healer" Cleric retainer from the S&F book, updated with the new rules, made a little <a href="https://ryandlewis.dev/assets/PDFs/Melisende.pdf">PDF handout</a> of her stats to give to the player for reference, and that was that.</p>
<p>I gave combat control of her to Kilomir's player, who seemed to be able to pick up on what he could do with her with little issue and only a small amount of guidance from me as the DM. The addition of a Retainer didn't seem to slow the game down much, if at all, or terribly unbalance the encounter, which are really all you can ask for. Overall, very happy with the system so far!</p>
<h3 id="minions" tabindex="-1">Minions</h3>
<p>From the same preview PDF, MCDM also introduced rules for Minions, in the style of 4th edition D&D, but revamped and revised for 5e. This was another thing I really wanted to try, and since I already had a zombie encounter planned and the PDF included a sample zombie minion, it seemed meant to be! These rules allow you to inundate your PCs with swarms of low-health enemies that are weak individually but dangerous in hordes.</p>
<p>Overall, I found the system worked pretty well, and definitely was faster than running 12 individual zombies with their own action, movement and bonus action. It has a nice system for bundling up multiple attacking minions into a single attack roll per target. The overkill mechanics are also nice.</p>
<p>I suspect the most challenging aspect of using these guys properly will ultimately be balancing encounters. This combat encounter wasn't meant to be brutally difficult, more just ominously foreshadowing, but I was a little surprised at how easily the party dispatched the horde. Part of that was because I made the mistake of starting the zombies too far away, giving the PCs ample time to hit them at range and thin the herd. But the other part was that I suspect the CR math overestimated the threat involved. But nobody has ever accused 5e's CR system of being infallible.</p>
<p>I did find the mechanics around spell saves unintuitive enough that I had to stop and look them up, which didn't feel great, but I understand the design decisions behind it and think the way it currently works is probably for the best. I imagine it'll be better once I can remember it off the cuff.</p>
<h3 id="conclusion" tabindex="-1">Conclusion</h3>
<p>Maybe not my best session, but the players seemed to have fun and I got to try out some fun MCDM goodies I've been meaning to find an excuse to use. And hey, at least I can blame any problems that came up during the session on illness.</p>
<footer role="doc-endnotes" class="Footnotes">
<h2 id="footnotes-label" class="Footnotes__title">Footnotes</h2>
<ol class="Footnotes__list"><li id="1-note" class="Footnotes__list-item" role="doc-endnote">The city the party has been calling home for the majority of the campaign. <a class="Footnotes__back-link" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#1-ref" aria-label="Back to reference 1" role="doc-backlink">↩</a></li>
<li id="2-note" class="Footnotes__list-item" role="doc-endnote">They had requested Melisende's presence as part of their deal to look into the problem (plague outbreaks have been cropping up in the region, so the party wanted to have a healer on hand). <a class="Footnotes__back-link" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#2-ref" aria-label="Back to reference 2" role="doc-backlink">↩</a></li>
<li id="3-note" class="Footnotes__list-item" role="doc-endnote">At least this had the benefit of waking the rest of the party. <a class="Footnotes__back-link" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#3-ref" aria-label="Back to reference 3" role="doc-backlink">↩</a></li>
<li id="4-note" class="Footnotes__list-item" role="doc-endnote">'Charge' is relative, zombie's speed being what it is. <a class="Footnotes__back-link" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#4-ref" aria-label="Back to reference 4" role="doc-backlink">↩</a></li>
<li id="5-note" class="Footnotes__list-item" role="doc-endnote">Some sort of respiratory bug. Tests say not COVID, but who can say at this point. Either way, we play over discord, so no players were at risk of IRL plague from the session. <a class="Footnotes__back-link" href="https://ryandlewis.dev/posts/ttrpg/thebandoleers026/#5-ref" aria-label="Back to reference 5" role="doc-backlink">↩</a></li></ol>
</footer>
Introducing DM's Log: Supplemental2022-05-05T00:00:00Zhttps://ryandlewis.dev/posts/ttrpg/introducingdmslog/<blockquote>
<h2 id="dm's-log%3A-supplemental" tabindex="-1">DM's Log: Supplemental</h2>
<p><em>Date: 2022-05-05.</em></p>
<p><em>Session: N/A</em></p>
<p>At last, I've discovered it! The nerdiest possible thing I could spend my time doing: writing about my Dungeons and Dragons games on the internet.</p>
<p>This will be the first in a series of logs recounting my experiences as an aggressively mediocre Dungeon Master attempting to run half decent games in between work and grad school.</p>
</blockquote>
<h2 id="why%3F" tabindex="-1">Why?</h2>
<p>A little experiment I'm trying. I want to practice writing more often (fun writing, not just code, emails, project reports, and academic papers). And I figure, what better way to do it than cataloging the shenanigans of my semi-regular D&D games?</p>
<p>I'm also hoping to include a little bit of reflection on each game, how I thought it went, and how I think I can improve. Hopefully, that will be useful for other DM's as well, but if nothing else it should help me.</p>
<h2 id="what-games%3F" tabindex="-1">What Games?</h2>
<p>Currently, I'm DMing one game with plans to start a fairly ambitious project this summer. I may also write about some of the games I play in, if the mood strikes me, though I just wrapped up one game and the other I regularly play in is on indefinite hold.</p>
<h3 id="the-bandoleers" tabindex="-1">The Bandoleers</h3>
<p>A scrappy group of adventurers grappling with a mysterious outbreak of undead and plague, the many dangers of open road and claustrophobic dungeon, and the struggles of operating a small business; all set in the homebrew world of Corithynn.</p>
<p>Starring:</p>
<ul>
<li>Kilomir, Minotaur Wild-Magic Barbarian
<ul>
<li>The muscle of the group</li>
<li>Trying to learn how to craft Dragonborn Plate Armor</li>
</ul>
</li>
<li>Faegwyn Suithrasas, High Elf School of Evocation Wizard
<ul>
<li>Resident grumpy old man</li>
<li>Trying, with varying degrees of success, to expand the Wagonline business that he inherited after the unfortunate death of the previous proprietor at the vicious claws of a flock of cockatrice</li>
</ul>
</li>
<li>Ollie, Tiefling Way of the Long Death Monk
<ul>
<li>Mandatory party Edgelord</li>
<li>Has the unique ability to see and speak with the Gods of Corithynn</li>
</ul>
</li>
<li>Mick Nichols, Rock Gnome Assassin Rogue
<ul>
<li>Accompanied by his trusty sidekick/mount, a Giant Duck named Lumpy</li>
</ul>
</li>
</ul>
<p>In the next session (Session 026), the Bandoleers are heading out from the relative safety of their current port of call, the Drunkard's City Dmittlock, and making a 3-day trek to an old fort called the Westerwatch that has stopped sending its regular reports.<br />
With one patrol of the City Watch already sent to investigate and seemingly lost, they're expecting trouble.<br />
They got this particular gig by striking a deal with the head of the Privy Council of Dmittlock to figure out what's going on in exchange for a hefty chunk of change and the opportunity to further some of their party goals.</p>
<h3 id="empyrea-lost" tabindex="-1">Empyrea Lost</h3>
<p>This is my secret summer project. More details to come!</p>
How to Install and Use Docker in WSL22022-03-06T00:00:00Zhttps://ryandlewis.dev/posts/howtowsldocker/<p><em>Edit: It's come to my attention that, since I figured out this workaround back when WSL2 and thus Docker's WSL2 backend were new, Docker Desktop for Windows has added support for using Docker from within your WSL2 distro. This obviates the need to install Docker within a WSL2 distro in most cases. But if you find yourself in a position where you can't or don't want to use the Docker Desktop support, read on.</em></p>
<p>Say you want to run a Linux environment on a Windows machine, and in that environment one of the things you want to do is make use of docker containers. Here's the quick and dirty way to get that set up:</p>
<h2 id="install-wsl" tabindex="-1">Install WSL</h2>
<p>Nowadays, this should be as simple as <code>Win+X</code>, selecting <code><Command Prompt/Powershell/Windows Terminal> (Admin)</code>, and running <code>wsl --install</code>.</p>
<p>If that doesn't work, or you want to fiddle/customize/use a non-default distro, check out <a href="https://docs.microsoft.com/en-us/windows/wsl/install">Microsoft's guide here</a>. Make sure you install a WSL2 distro.</p>
<p>For the rest of this, I'm assuming you've installed the default Ubuntu Distro, steps might be slightly different for other distros.</p>
<h2 id="verify-and-setup-wsl" tabindex="-1">Verify and Setup WSL</h2>
<p>Make sure that the distro you just installed is a WSL2 distro, as you can't run docker in WSL1.</p>
<pre><code># Set the default version to 2
wsl --set-default-version 2
# Check that the distro you installed is version 2
wsl -l -v
# Upgrade a v1 distro to v2
wsl --set-version <distro-name> 2
</code></pre>
<p>If you're having trouble upgrading the distro, see <a href="https://docs.microsoft.com/en-us/windows/wsl/install#ways-to-run-multiple-linux-distributions-with-wsl">here for help</a>.</p>
<p>Now, open the "Ubuntu" application that you just got installed, and set your username and password. Do package updates, install whatever tools and packages you want, and just generally make yourself at home.</p>
<h2 id="install-docker" tabindex="-1">Install Docker</h2>
<p>Follow <a href="https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository">these setup instructions</a> (if you chose to install a distro other than Ubuntu, find the appropriate install guide on the left of that page).</p>
<p>Stop before running <code>sudo docker run hello-world</code>.</p>
<h2 id="configuring-docker-on-wsl2" tabindex="-1">Configuring Docker on WSL2</h2>
<h3 id="using-docker-without-invoking-root" tabindex="-1">Using Docker Without Invoking Root</h3>
<p>Don't want to have to run docker commands with <code>sudo</code> all the time? <a href="https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user">Follow this guide to add yourself to the docker group</a>.</p>
<h3 id="starting-the-docker-daemon" tabindex="-1">Starting the Docker Daemon</h3>
<p>One hiccup with docker in WSL2 is that it doesn't automatically start the Docker service. The simple but annoying solution is to run <code>sudo service docker start</code> whenever you want to use Docker.</p>
<p>If you don't want to have to remember and invoke that command every time, you can add the following to your "~/.profile", or your shell configuration file like "~/.bashrc":</p>
<pre><code>if [ -n "`service docker status | grep not`" ]; then
sudo /usr/sbin/service docker start
fi
</code></pre>
<p>Now this has the annoying side effect of making you have to type out your sudo password whenever you start WSL2 for the first time.</p>
<p>To fix this, you can run <code>sudo visudo -f /etc/sudoers.d/passwordless_docker_start</code>, add the following to the file (replacing <code>username</code> with your Linux username), save and close. (<a href="https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers-file">See here to learn more about the intricacies and nuances of sudoer files</a>)</p>
<pre><code>username ALL = (root) NOPASSWD: /usr/sbin/service docker start
</code></pre>
<p>Now, the docker service automatically starts in WSL2 without requiring authentication, and you can use it more or less exactly like you would use Docker on a regular Linux install.</p>
<p>Cover Photo by <a href="https://www.pexels.com/@tomfisk?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels">Tom Fisk</a> from <a href="https://www.pexels.com/photo/aerial-view-photography-of-container-van-lot-1427107/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels">Pexels</a>.</p>
How to Communicate with an Arduino from Docker2021-03-14T00:00:00Zhttps://ryandlewis.dev/posts/howtoarduinodocker/<p>Something I learned this weekend. Let's say you have an Arduino, and you want to communicate with it via serial from a Linux device, like a Jetson Nano. But not from that device's host operating system. No, that'd be too easy.</p>
<p>Instead, you want to talk with this Arduino from an application running in an unprivileged Docker container. How would you do that?</p>
<h2 id="how-to-bring-an-arduino-inside-docker" tabindex="-1">How To Bring an Arduino inside Docker</h2>
<p>It turns out it's actually quite simple! When connected to a Linux device via a USB cable, most Arduino's show up as a device in the form <code>/dev/ttyAMCx</code> where x is replaced with an integer counter, starting from 0. So the first Arduino you connect is <code>/dev/ttyAMC0</code>, the second is <code>/dev/ttyAMC1</code> and so on.</p>
<p>To access that from Docker, all you need is the docker <code>--device</code> flag. Include it in the docker run command as <code>docker run <other options> --device="/dev/ttyACM0" <more options, image name, etc></code> and you're all set. You can access the Arduino in the container at <code>/dev/ttyACMx</code> just like you would on the host, say with the <code>pyserial</code> package in Python.</p>
<h2 id="words-of-warning" tabindex="-1">Words of Warning</h2>
<p>Couple quick notes:</p>
<ol>
<li>You need to have the device connected before you launch your docker container with that flag. Otherwise, you'll get an error.</li>
<li>You may run into issues if the device is disconnected and reconnected while the container is running.</li>
<li>Serial over wires (for instance, with jumper cables connecting pins on the arduino to GPIO on a Jetson or Raspberry Pi) rather than via the USB port will probably have a different device file handle, but will function the same way (pass the device file handle into the container with <code>--devices</code>.</li>
</ol>
⌨ MCK142Pro.ahk2021-02-28T00:00:00Zhttps://ryandlewis.dev/projects/mck142pro/<p>Project Link: <a href="https://gist.github.com/LuckierDodge/2ed678e035306d7f3cd935a40b3b0028">https://gist.github.com/LuckierDodge/2ed678e035306d7f3cd935a40b3b0028</a></p>
<p>Description: <em>An AutoHotKey script that I use to extend the functionality of an MCK142Pro programmable mechanical keyboard.</em></p>
<p>I wrote a whole <a href="https://ryandlewis.dev/posts/mck142pro">post</a> about this project! In short, I took a thrift store mechanical keyboard from the 90s and figured out how to make it a budget Stream Deck for the 2020s.</p>
Extending an Old-school Programmable Keyboard with AutoHotKey2021-02-23T00:00:00Zhttps://ryandlewis.dev/posts/mck142pro/<h2 id="so-it-begins..." tabindex="-1">So it Begins...</h2>
<p>Our tale begins in December of 2020 with a message from my friend, roommate, and a notorious thrifter/dumpster diver extraordinaire, Jorge (name changed to protect the innocent) asking if I was interested in an old mechanical keyboard from the thrift store, still in the original packaging.<br />
The message came with a picture of the front of the box, from which little information could be gleaned except the words "TWENTY-FOUR PROGRAMMABLE KEYS".<br />
Like any good computer nerd, I said "Absolutely!".<br />
So he picked up two, one for himself and one for me, for a crisp $3 USD each.</p>
<p>When he returned with his loot, I quickly set to figuring out what, exactly, we had on our hands.<br />
These were brand-new in the box keyboards, and the box said <em>MCK-142 Pro</em>...and not much else.<br />
Not even a manufacturer.<br />
But a name's as good a place to start as any, and I turned to the internet and my search engine of choice to look for clues.</p>
<p>And that's where I found <a href="http://www.mck142.com/">http://www.mck142.com/</a>, a lovely little time capsule/memorial devoted to this keyboard specifically.<br />
I encourage you to click through and appreciate this website for a moment (it doesn't take too long to read in its entirety, and it's such a lovingly crafted little webpage).</p>
<h2 id="getting-to-know-the-mck-142-pro" tabindex="-1">Getting to Know the MCK-142 Pro</h2>
<p>For those of you who didn't click through, I'll give you a quick rundown of this keyboard's features</p>
<ul>
<li>Satisfyingly Clicky Mechanical Switches</li>
<li>Two sets of Function Keys: the standard top row and a "Left-handed" column on the left side of the main keyboard</li>
<li>8-directional arrow keys (that's right, this thing can move the cursor diagonally with a single keypress)</li>
<li>Coiled PS2 cable</li>
<li>A Fast Repeat Key. According to the manual, this bumps the keyboard from a default of 10 Characters Per Second (CPS) when a key is held, to a crisp 20 CPS with the Fast Repeat Key.</li>
<li>24 Programmable Keys</li>
<li>8K (as in, Kilobytes) of Onboard CMOS SRAM Memory, maintained by a set of 4(!) AA batteries (not included, thankfully. Otherwise they'd be a corroded mess by now)</li>
<li>A floppy disk with software for programming the aformentioned Programmable Keys</li>
</ul>
<p>Some of this functionality has been rendered obsolete by the passage of time, of course.<br />
The "Fast Repeat" key, which would allow the user to more quickly enter the same key when holding it down, is superseded by the host operating system's settings on key repeats and associated delays these days.<br />
The floppy disk with included software for programming may still be usable on some IBM PC's from the 90s, but I wasn't about to try and find out.</p>
<p>Notably, it does not feature a Windows Key, because it wasn't really intended for use with Windows NT-based computers, but <a href="https://github.com/microsoft/PowerToys">PowerToys'</a> key remapping utility solves that (in my case, I remapped the Caps Lock key, a key which I ONLY press accidentally).</p>
<p>The keyboard itself very much reminds me of the old Gateway family PC we had when I was growing up, with the same solid square body, weighty heft, and lightly textured beige ABS with gray accents.<br />
I've never had too much nostalgia for that era of computing (I mostly remember that PC for being slow, noisy, and prone to crashes), but it's well-built, if nothing else.</p>
<div class="image">
<p><img src="https://ryandlewis.dev/assets/images/mck142pro/keyboard.jpg#responsiveimage" alt="The MCK142Pro Keyboard and Manual, sitting on a desk." /></p>
</div>
<h2 id="programming-the-programmable-keyboard" tabindex="-1">Programming the Programmable Keyboard</h2>
<p>Now, I had to figure out how to program this beauty.<br />
At first, I was concerned that, without the software working (aka, without an IBM PC or some sort of emulator), I'd be unable to actually program the keyboard.<br />
Not the end of the world, but disappointing to relinquish such unique functionality.</p>
<p>Thankfully, a detailed reading of the manual revealed that this was not the case!<br />
In addition to the 24 Programmable Keys, the keyboard has a "Select" key and two LEDs: "Menu" and "Prog".<br />
As it turns out, that key could be used to program each of the 24 keys, with the following steps (taken word for word out of the manual):</p>
<ol>
<li>Press the SELECT Key twice within a second, the PROG LED indicator in YELLOW will turn on.</li>
<li>Press one PF Key, e.g. any one of PF1 to PF24, to start data entry.</li>
<li>Type strings or commands you want to save in any one of PF keys by using keyboard typewriter keys. The keystrokes of every PF key is limited within 320 keystrokes.</li>
<li>Press the SELECT Key once to save the data to the chosen PF Key, the PROG LED indicator in YELLOW will flash once.</li>
<li>Repeat the action from 2. to 4. for defining others or redefining any PF keys.</li>
<li>Press the SELECT Key one more time to complete data entry, the PROG LED indicator in YELLOW will turn off.</li>
</ol>
<p>So, for instance, if I wanted to map the <code>PF1</code> key to something like <code>Ctrl+Shift+V</code>, I could do that by:</p>
<blockquote>
<p>Pressing <code>SELECT</code> twice, pressing <code>PF1</code>, typing <code>Ctrl+Shift+V</code>, pressing the <code>SELECT</code> key, and then pressing the <code>SELECT</code> key again to exit.</p>
</blockquote>
<p>Now, the manual did forget to mention something: how to actually use the <code>PF</code> keys.<br />
After programming one of the keys, I found that pressing it didn't actually do anything.<br />
Perplexing.</p>
<p>With the quest teetering on the edge of disaster, I set out to find a solution.<br />
After some experimentation, I discovered that I needed to press the <code>SELECT</code> key once to activate the <code>PF</code> keys. When I did that, the Menu LED lit up green and the <code>PF</code> keys would work.<br />
Without it, no dice.<br />
Moreover, this needed to be done anytime the computer was restarted or the keyboard was disconnected.<br />
Easy enough, but strangely, not mentioned anywhere in the manual.<br />
I can't help but think the software might automatically handle that functionality, but without it the keys have to be manually toggled.</p>
<h2 id="extending-with-autohotkey" tabindex="-1">Extending with AutoHotKey</h2>
<p>Now at this point, I can program the keys to do essentially anything I can do on my keyboard (with 320 keystrokes, at least).<br />
This includes both entering hotkeys and typing text (or a mix of both), which is neat, but I wanted to push it further.<br />
After all, I could already use hotkeys by...pressing the hotkey.</p>
<p>Naturally, the first thing I did once I got programming working was program it to type <a href="https://knowyourmeme.com/memes/the-tragedy-of-darth-plagueis-the-wise">The Tragedy of Darth Plagueis the Wise</a> at the press of a button.<br />
There are rules, after all.</p>
<p>But how to make this actually useful?<br />
The use cases suggested by the keyboard were things like passwords, email signatures, and other text you have to repeat often.<br />
But I've found that most of these scenarios have been solved by password managers, built-in email signatures, and other software approaches.<br />
Plus programming passwords or other sensitive information into a keyboard really sets my security spider-senses atingling.</p>
<p>What I really wanted to do with this keyboard, was configure it such that I could essentially trigger an arbitrary action on my computer with each button.<br />
And I wanted to be able to easily change what each <code>PF</code> key would do (typing out the whole Tragedy of Darth Plagueis takes awhile, after all).</p>
<h3 id="enter-autohotkey" tabindex="-1">Enter AutoHotKey</h3>
<p>To do that, I turned to <a href="https://www.autohotkey.com/">AutoHotKey</a>, the self-proclaimed "ultimate automation scripting language for Windows".<br />
It's a powerful tool, capable of a great many things, but for our purposes, it provides us with a way to create custom hot keys that can trigger a wide range of things: run one or more programs, manage which windows are open and active, type text, make decisions based on whats happening on the computer, and more.<br />
Moreover, these hotkeys and outcomes are laid out in a script, which can be quickly modified and restarted to change the effect of a given hotkey.</p>
<p>One wrinkle quickly presents itself, however.<br />
AutoHotKey works by intercepting values from the keyboard.<br />
For instance, if I type <code>Ctrl+Shift+J</code>, and I have an AutoHotKey script with that hotkey programmed as a trigger, the corresponding actions will be run when <code>Ctrl+Shift+J</code> is detected.<br />
But the <code>PF</code> keys aren't really keys, at least, not from the Operating System's perspective.<br />
When a <code>PF</code> key is pressed, the only keys the computer sees are whatever strokes the key was programmed to type.<br />
So I can't have an AutoHotKey script listen for the <code>PF</code> keys directly, I have to have it listen for a special hot key which I program into each <code>PF</code> key.</p>
<p>Since I don't want the AutoHotKey hooks to trigger when I press something other than a <code>PF</code> key, these can't be hotkeys I need to use regularly.<br />
And I don't want the AutoHotKey functionality to mask actual functionality, either.</p>
<p>So I set out to find a set of 24 hotkeys not used anywhere else on my computer.<br />
And I almost succeeded.<br />
The closest I got was with the pattern <code>Ctrl+Alt+Shift+Fx</code>, where <code>Fx</code> corresponds to <code>PFx</code>, i.e. <code>PF1:F1</code>, <code>PF2:F2</code>, etc.<br />
Now, you'll quickly realize there's a problem here: I have 24 programmable keys, but only 12 function keys.<br />
Not to fear, as it turns out AutoHotKey can differentiate between left and right modifier keys! So I set the first 12 <code>PF</code> keys to use the left control key, and the last 12 to use the right control key.</p>
<p>Unfortunately, exactly one of these shortcuts (the <code>F7</code> combo, I think) is actually already mapped to some obscure function of Nvidia's GeForce Experience software.<br />
But since I had never used that functionality or key combo before in my life, I decided that was okay.<br />
This specific pattern of hotkeys may not work for everyone, but it worked for my purposes.</p>
<p>Notably, this approach confers another advantage: even without this particular keyboard, I can still use my AutoHotKey setup, because they just correspond to (awkward, inconvenient) hotkeys.<br />
The Programmable keyboard provides a simple, clean interface from which I can trigger whatever functionality I want with the press of a single button now.</p>
<h3 id="the-autohotkey-script" tabindex="-1">The AutoHotKey Script</h3>
<p>So what does the script look like, and what am I actually doing with it?<br />
<a href="https://gist.github.com/LuckierDodge/2ed678e035306d7f3cd935a40b3b0028">Here's a Gist</a> of the full version, but I'll break it down below.</p>
<p>We start with some opening configuration, which are pretty much the defaults for a new AutoHotKey script:</p>
<pre><code>#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
</code></pre>
<p>Then, we add 24 of the following, slightly modified to match each <code>PF</code> key:</p>
<pre><code>; PF1
<^!+F1::
Run, wt
return
</code></pre>
<p>The first line is a comment identifying the programmable key I'm creating a hotkey for (AutoHotKey uses semicolons for its comment character).<br />
The second is declaring the hotkey, broken up as follows:</p>
<ul>
<li><code><</code> indicates that we want the "left" version of the next modifier key</li>
<li><code>^</code> corresponds to the control key in AutoHotKey parlance.</li>
<li><code>!</code> corresponds to the alt key</li>
<li><code>+</code> corresponds to the shift key</li>
<li><code>F1</code> corresponds to the first function key</li>
<li><code>::</code> indicates the end of our hotkey, with everything after it corresponding to what should happen after the hotkey is detected.</li>
</ul>
<p>This brings us to the third line <code>Run, wt</code> which, as the name implies, runs a program.<br />
In this case, its running the <code>wt</code> shortcut, which opens the Windows Terminal, but you could replace that with any shortcut name or path to an application.<br />
Basically, it works the same as the Windows Run dialog accessed with <code>Win+r</code>.</p>
<p>But we're not limited to running just a single command. Consider,</p>
<pre><code>; PF2
<^!+F2::
Run, outlook
Run, "C:\Users\Ryan Lewis\AppData\Local\Microsoft\Teams\Update.exe" --processStart "Teams.exe"
Run, "C:\Users\Ryan Lewis\AppData\Local\slack\slack.exe"
Run, "C:\Users\Ryan Lewis\AppData\Local\Discord\Update.exe" --processStart Discord.exe
return
</code></pre>
<p>which opens all of my various communications applications. I just switch to an empty virtual desktop, press <code>PF2</code>, and it opens Outlook, Teams, Slack, and Discord. With <a href="https://github.com/microsoft/PowerToys">PowerToys'</a> Fancy Zones, it even nicely positions them in the same grid pattern every time.</p>
<p>Last but not least, my proudest creation so far:</p>
<pre><code>; PF3
<^!+F3::
WinHTTP := ComObjCreate("WinHTTP.WinHttpRequest.5.1")
WinHTTP.Open("GET", "https://wttr.in/12345?nFATQ")
WinHttp.Send()
response := WinHTTP.ResponseText
Gui, New,, Weather Report
Gui, Color, 111111
Gui, Font, s14 cWhite, Cascadia Mono
Gui, Add, Text,, % response
Gui, Show
return
</code></pre>
<p>Which sends an HTTP request to the wonderful <a href="https://wttr.in/">wttr.in</a> weather API, and displays the results in a helpful dialog.<br />
I won't bore you with the details of how it works, but I think it's a simple example of some of the powerful potential here: anything I can hook up to an API endpoint, I can run with the press of a button.</p>
<div class="image">
<p><img src="https://ryandlewis.dev/assets/images/mck142pro/weather-dialog.png#responsiveimage" alt="The Weather popup that I see when I press PF3, complete with adorable ASCII art." /></p>
</div>
<h2 id="denouement" tabindex="-1">Denouement</h2>
<p>To summarize, I took an old programmable mechanical keyboard, combined it with the power of AutoHotKey, and found a needlessly complicated way to create a budget <a href="https://www.elgato.com/en/gaming/stream-deck">Stream Deck</a>.<br />
Compared to the $150 price tag for one of those, $3 and some elbow grease doesn't seem half bad.<br />
And, more importantly, it was pretty fun to figure out!</p>
<p>I'm not done with this project just yet: I hope to find some more useful shortcuts to map, as well as integrating into my homelab/self hosting.<br />
Once I get Home Assistant setup, for instance, it would be fun to hook up buttons to some automations.<br />
Of course, I'll update the Gist as I go.</p>
<p>Got any suggestions, questions, or thoughts? What would you map these buttons to? Let me know! Otherwise, support open source projects, and be nice to each other out there!</p>
🖊 Graphics Modeling2020-12-01T00:00:00Zhttps://ryandlewis.dev/projects/graphics/<p>Project Link: <a href="https://ryandlewis.dev/projects/graphics">https://ryandlewis.dev/projects/graphics</a></p>
<p>Description: <em>Some artifacts from my graphics modeling efforts that I think don't look half bad. All programmatically generated using a RenderMan-based graphics pipeline.</em></p>
<div class="image">
<p><img src="https://ryandlewis.dev/assets/images/graphics/BezierPatches.png#responsiveimage" alt="Bezier Patches" title="Bezier Patches" /></p>
<p><em>Bezier Patches</em></p>
<p><img src="https://ryandlewis.dev/assets/images/graphics/Fractal4.png#responsiveimage" alt="Fractal 4" title="Fractal 4" /></p>
<p><em>Fractal 4</em></p>
<p><img src="https://ryandlewis.dev/assets/images/graphics/Fractal5.png#responsiveimage" alt="Fractal 5" title="Fractal 5" /></p>
<p><em>Fractal 5</em></p>
<p><img src="https://ryandlewis.dev/assets/images/graphics/Fractal6.png#responsiveimage" alt="Fractal 6" title="Fractal 6" /></p>
<p><em>Fractal 6</em></p>
<p><img src="https://ryandlewis.dev/assets/images/graphics/SuperquadricSphere.png#responsiveimage" alt="Superquadric Spheres" title="Superquadric Spheres" /></p>
<p><em>Superquadric Spheres</em></p>
<p><img src="https://ryandlewis.dev/assets/images/graphics/SuperquadricTori.png#responsiveimage" alt="Superquadric Tori" title="Superquadric Tori" /></p>
<p><em>Superquadric Tori</em></p>
</div>
Personal Notes from ROS World 20202020-11-12T00:00:00Zhttps://ryandlewis.dev/posts/rosworld2020/<blockquote>
<p><em>Update: You can find all of the videos from ROS World 2020 <a href="https://vimeo.com/showcase/rosworld2020">here</a>.</em></p>
</blockquote>
<p>I attended the Robotic Operating System's <a href="https://roscon.ros.org/world/2020/">ROS World 2020</a> convention today. I quite enjoyed it! To keep myself focused during the event, I tried to write some comprehensive notes. To keep myself entertained, I wrote them as if somebody else would be reading them.</p>
<p>But it occurred to me that someone else might find these useful in some way, especially if they missed the convention or didn't know it was a thing, and this might act as a sort of helpful guide. Or maybe you're just curious about robots and want to see what we're up to. Either way, I hope this is helpful! I'll add links to the videos once they're posted publicly, and will happily answer any questions in the comments.</p>
<h2 id="%F0%9F%94%91-keynote-%26-q%26a---dr.-vivian-chu%2C-co-founder-and-cto-of-diligent-robotics" tabindex="-1">🔑 Keynote & Q&A - Dr. Vivian Chu, co-founder and CTO of Diligent Robotics</h2>
<ul>
<li>Missed the first couple minutes because the stream was acting up.</li>
<li>Good advice on robotics startups</li>
<li>Interesting insight into systemic issues in healthcare and nursing, and how robots might be able to help alleviate that.</li>
<li>Users don't know what they want</li>
<li>Spotty network connections, even indoors</li>
<li>Q & A Bechdel Test: Two women - Katherine Scott, Developer Advocate from Open Robotics, and Dr. Vivian Chu, CTO of Diligent Robotics. Other founder of Diligent is also a woman.</li>
</ul>
<h2 id="%F0%9F%91%8D-panel%3A-software-quality-in-robotics-content" tabindex="-1">👍 Panel: Software Quality in Robotics Content</h2>
<ul>
<li>Deby Katz - Carnegie Mellon University (Moderator), Allison Thackston - Waymo, Afsoon Afzal Phd Candidate at Carnegie Mellon, Sophia Kolak from Columbia University</li>
<li>So many women speakers! Awesome.</li>
<li>Familiar idea for most devs: automated testing is important</li>
<li>Adversarial situations: robots have to exist in the real world, where things often don't go to plan.</li>
<li>FIELD TESTING, LOGGING AND PLAYBACK - IMPORTANT</li>
<li>Not as much Automated Testing currently, because it's hard, but might be helpful to increase</li>
<li>3 Main Challenges:
<ul>
<li>Testing in the real world ("Unknown unknowns")</li>
<li>She never actually mentioned the other 2</li>
</ul>
</li>
<li>Sensor noise makes things interesting.</li>
<li>"Degenerate Input"</li>
<li>Lots of dichotomization between pure software like the web and these physical computing concepts.</li>
<li>Documentation for packages are lacking.</li>
<li>Need to reduce friction for writing documentation.</li>
<li>Simulation is critical part of software quality assurance
<ul>
<li>Why aren't people using it then?</li>
<li>Using "multiple modalities of testing" can improve testing</li>
</ul>
</li>
<li>Favorite/most interesting bug
<ul>
<li>Someone found simulated case where robot arm intersected robot body, developers didn't believe, sure enough: broke robot</li>
<li>Simulators can be wonky: spawn underground, shoot up and collapse in on itself.</li>
<li>Robot kicked human tester so hard they were injured during field testing.</li>
</ul>
</li>
<li>Software testing important for researchers?
<ul>
<li>Yes (implied <em>duh</em>)</li>
<li>Too many people treat it as an afterthought</li>
<li>Need to make it easy to go from rosbag to structured unit test</li>
<li>The infrastructure and techniques need robustness</li>
<li>First-to-market tends to outweigh safety/quality concerns
<ul>
<li>Maybe need to introduce standard/certification</li>
</ul>
</li>
</ul>
</li>
<li>Probabalistic Testing, how do we ensure coverage?
<ul>
<li>Better test platform, increase reproducibility, add fuzziness to try and replicate</li>
</ul>
</li>
<li>Health of the ROS ecosystem
<ul>
<li>Software Quality/Testing is hidden away in the far corners of specialized CS curriculum
<ul>
<li>Need to prioritize teaching these tools</li>
</ul>
</li>
<li>Need better tooling</li>
<li>AUTOMATE. THOSE. TOOLS!!!</li>
<li>Standardized Environments for testing - neat!</li>
</ul>
</li>
<li>Best practices?
<ul>
<li>Lot of familiar stuff from traditional software engineering</li>
<li>How do you style a test environment to do end-to-end testing</li>
<li>Lotta roll-your-own right now</li>
<li>Documentation for best practices/testing is lacking</li>
<li>MOAR TOOLING</li>
<li>If you have something that works/you've created, share it with the community!</li>
<li>Lots of dependency on a few centralized packages - dangerous</li>
</ul>
</li>
<li>Hardware in the Loop Testing
<ul>
<li>Need to look into this more.</li>
<li>Simulation is great, but some things are hardware-dependent.</li>
<li>Different types of tests to get different types of results</li>
<li>Log testing gives rare, real results that might never appear in simulation</li>
</ul>
</li>
<li><strong>"At the end of the day, you need a reliable system, and a reliable system is well tested."</strong></li>
<li>Even if simulation can't catch everything, it's better than nothing.</li>
<li>Code maintainers and reviewers could be requiring documentation with new pull requests.</li>
<li>Make documentation/testing a part of community standards.</li>
<li>No set of well-defined best practices for software quality. How do we fix that?
<ul>
<li>Community standards, again.</li>
<li>People look to OSRF for standards, so maybe starting there.</li>
<li>Also maintainers of large packages.</li>
</ul>
</li>
</ul>
<h2 id="%E2%9A%A1-lightning-talks-1" tabindex="-1">⚡ Lightning Talks 1</h2>
<ul>
<li>Cool vis of ROS contributions over time.
<ul>
<li>Needs a legend for the colors.</li>
<li>Should've grabbed the link</li>
</ul>
</li>
<li>For some reason this conference platform keeps tripping the Firefox VR permissions. Do they have a WebXR viewer? Not willing to risk losing the stream again to figure out.</li>
<li>Ad for EProsima "The Middleware Experts"
<ul>
<li>Discovery server for ROS</li>
<li>Shared Memory</li>
</ul>
</li>
<li>Sidenote: videos are hosted on Vimeo. Good choice, I guess, given the youtube outage 🤷♂️</li>
<li>Robot Dogs!
<ul>
<li>Aibo</li>
<li>Had one as a kid, back when they were...not good. Wonder if they've gotten better? Hard to tell from ad.</li>
</ul>
</li>
<li>Ubuntu advertisement for snap
<ul>
<li>So fast, much snappy.</li>
<li>Look at that apt install, sped up to 4x and still trailing. What a scrub.</li>
</ul>
</li>
<li>Ooh, flashy "ROS Underground" ad
<ul>
<li>DARPA Subterranean Challenge.</li>
<li>Interesting, tools provided competition.</li>
<li>11/17/2020</li>
</ul>
</li>
<li>Daniel Grieneisen, Six River Systems
<ul>
<li>Shipping and warehousing robots</li>
<li>Flash backs to working back-end at Walmart <em>shudders</em></li>
<li><a href="https://6river.com/category/engineering">6river.com/category/engineering</a></li>
<li>Open source Data-processing pipeline, neat</li>
</ul>
</li>
<li>They weren't kidding about lightning, geez</li>
<li>These are some high-budget videos, wow.</li>
<li>Rocos
<ul>
<li>Some sort of ROS robot operations management tool</li>
<li>Widgets! Dashboards! Digital Twins! Autonomous missions! Visualizations! Fleets! Complexity! Security!</li>
<li><a href="https://rocos.io/">rocos.io</a></li>
</ul>
</li>
<li>ARM ad
<ul>
<li>"5th wave of computing"</li>
<li>Buzzwordy buzzwords are buzzwording.</li>
</ul>
</li>
</ul>
<h2 id="%F0%9F%8F%AB-time-for-class" tabindex="-1">🏫 Time for Class</h2>
<ul>
<li>If anyone wants my notes on Bezier Curves, let me know 😉</li>
<li>Missed: networking break (meh), "MSeg: Achieving Generality and Robustness in Semantic Segmentation".</li>
</ul>
<h2 id="%F0%9F%8C%B1-panel%3A-ros-agriculture" tabindex="-1">🌱 Panel: ROS Agriculture</h2>
<ul>
<li>Stream wasn't loading, so whatever occurred at the beginning is a mystery to me 😒</li>
</ul>
<div class="image">
<p><img src="https://dev-to-uploads.s3.amazonaws.com/i/7rthdv3daux0dnu4k58m.gif#responsiveimage" alt=""LET ME INNNNNNNNN"" /></p>
</div>
<ul>
<li>Got in, 20 minutes late</li>
<li>Sarah Osentoski (Moderator), SVP Iron OX; Michele Pratusevich, Direcotr of Software Development, Root AI; Lee Redden, Chief Scientist, Blue River Technology; Eitan Babcock, Chief Roboticist/Cofounder, American Robotics</li>
<li>...some stuff that I missed...</li>
<li>Need to couple engineering w/ extant agricultural knowledge from agronomists to achieve superior results</li>
<li>Robots can replicate grueling PhD research formerly done by hand, but much faster</li>
<li>Big push in CV using expert annotators - Ag is a good use case
<ul>
<li>Part of the job is to leverage the myopic knowledge of Ag researchers</li>
<li>Needs more love for 3D data - LIDAR, point clouds, etc.</li>
<li>Also change detection, time</li>
</ul>
</li>
<li>Is Ag easy, due to minimal human interaction?
<ul>
<li>"Don't know about easy, but different problem set".</li>
<li>Advantages: everything's on a grid, more control of certain variables and structure</li>
<li>No FDA testing like in medical</li>
<li>Fewer size and power, movement constraints</li>
<li>Limited ethical constraints (don't know about this one)</li>
<li>Hard: no red tape, so stuff needs to work. Farmers have "show me" culture, needs to withstand the elements, operate in variety of potentially adverse conditions.</li>
</ul>
</li>
<li>How do you deal with FDA requirements for cleaning tools etc?
<ul>
<li>Michele - "Thankfully, haven't had to deal with it yet"</li>
<li>As volume scales: might eventually have safety requirements, IP requirements, etc.</li>
<li>Learn as we go.</li>
<li>Sarah - difference between agriculture (in the field) and manufacturing (on the conveyor)</li>
</ul>
</li>
<li>Ever had to pivot areas in Ag?
<ul>
<li>Michele - not yet</li>
<li>Eitan - small shift from bulk to high-value crops.</li>
<li>Lee - pivoted form lawn mowers to tractors to implements; now some phenotyping.
<ul>
<li>Pivot from lettuce to row crops due to market size.</li>
<li>So many small subsegments in Ag, value-based priority shift/addition</li>
<li>Enabled by technology leap.</li>
</ul>
</li>
</ul>
</li>
<li>Connectivity issues?
<ul>
<li>Issues in greenhouse due to water content in air</li>
<li>Eitan - rely on LTE, problems if not near highway (most farms). Satellite also an option
<ul>
<li>Range on base station: point to point radio, multiple miles</li>
</ul>
</li>
<li>Michele - "Once we send robot out into the row, we assume we can't talk to it"
<ul>
<li>Also in greenhouse</li>
<li>Get data off robot at some point</li>
<li>Costs money and time to move data offsite</li>
<li>How do you prioritize data retention?</li>
</ul>
</li>
<li>Lee
<ul>
<li>Embed intelligence on the robot</li>
<li>If we have connectivity, that's a nice plus</li>
</ul>
</li>
</ul>
</li>
<li>How do you get buy-in from Farmers
<ul>
<li>Lee - farmers have been quite open and willing, straightforward with what's valuable and what isn't, allow demos and whatnot, constantly trying things and improving. Calculated risks</li>
<li>Michele - "part of it is relationship building", building trust slowly over time, can't destroy somebody's crop, demo what's possible. Onsite facility mocked up to demo stuff/use for marketing</li>
<li>Eitan - small pilot programs, work up to 6-month growing season.</li>
</ul>
</li>
<li>Advice for roboticists interested in Ag?
<ul>
<li>Michele - find your niche. Pick a pain point and solve that, not generalized problems</li>
<li>Eitan - agreeing noises to michele, communication is important and talk to farmers when they're not in the middle of growing season.</li>
<li>Lee - general roboticist? Apply to one of our companies!!</li>
</ul>
</li>
</ul>
<h2 id="%F0%9F%A5%AA-lunch-break-(technically-a-networking-break%2C-but-dammit-i-need-to-eat)." tabindex="-1">🥪 Lunch Break (Technically a Networking Break, but dammit I need to eat).</h2>
<h2 id="%E2%9A%A1-lightning-talks-2" tabindex="-1">⚡ Lightning Talks 2</h2>
<ul>
<li>Spinning circle of doom. At least it's better than the black screen from earlier, I guess.</li>
<li>Welp, someone posted the permalink, so here it is: <a href="https://vimeo.com/478302472">https://vimeo.com/478302472</a></li>
<li>Also, Vimeo needs to leave my VR headset alone for pity's sake.</li>
<li><a href="http://apex.ai/">Apex.AI</a> ad: self-driving stuff
<ul>
<li>Autonomous is hard, yo</li>
<li>ApexOS</li>
</ul>
</li>
<li>ROS2 in RoboCup
<ul>
<li>Autonomous soccer bots!</li>
<li>Adorably janky</li>
<li>Lots of different components, really leveraging ROS for this</li>
<li><a href="https://gitlab.com/boldhearts">https://gitlab.com/boldhearts</a></li>
</ul>
</li>
<li>AWS Robotics Ad
<ul>
<li>I'm too poor for your product, Roger.</li>
<li>They do have a lot of integrated ROS extensions</li>
<li>Big emphasis on simulation and WorldForge stuff</li>
<li>Free Robotics Application Development Curriculum - Might be a good alternative to ROS Construct</li>
</ul>
</li>
<li>8:02 going to other session, will come back to this later</li>
<li>...</li>
<li>And we're back.</li>
<li>Fetch Robotics
<ul>
<li>History of ROS montage</li>
<li>Robots helping with COVID!</li>
</ul>
</li>
<li>roscompile ad
<ul>
<li>Hate using CMake? roscompile makes all that nonsense less awful</li>
<li>Thankfully, much less of that in ROS2</li>
</ul>
</li>
<li>ClearPath Robotics
<ul>
<li>Maker of nice rugged all terrain robots of various classifications</li>
<li>Love how industrial their mobile robots are</li>
</ul>
</li>
<li>Rapyuta Robotics ad
<ul>
<li>More warehouse robots</li>
</ul>
</li>
</ul>
<h2 id="%F0%9F%8C%8D-moveit-world" tabindex="-1">🌍 MoveIt World</h2>
<p>Lots of different technical sessions at 1:45pm, I chose this one because it's relevant to stuff I want to do in the near future. Might go back and explore the other talks later.</p>
<p>For those who don't know, MoveIt is a tool for motion planning with robotic arms.</p>
<ul>
<li>9(!) presenters, including a number from PickNik (primary contributors to MoveIt).</li>
<li>World MoveIt day Hackathon
<ul>
<li>Closed many issues and pull requests</li>
<li>80 participants, 55 people signed up on discord</li>
</ul>
</li>
<li>MoveIt on Discord and Discourse</li>
<li>MoveIt2 out of beta now</li>
<li>RoadMap Status Update
<ul>
<li>Already have straight port to ROS 2 94% complete</li>
<li>Currently refactoring for Realtime support
<ul>
<li>"Reactive, closed loop control"</li>
<li>"Separate global and local planner (hybrid planning)"</li>
<li>"Zero Memory Copy Integration"</li>
<li>Integrate pilz_industrial_motion</li>
</ul>
</li>
<li>Cool motion planning demos</li>
<li>Lots of movement here: Google Summer of Code, Hackathons, research interns, and a well coordinator core contributors group. It's an impressive open source org, to be sure.</li>
<li>Lots of features around pose-planning, moving the arm in intelligent ways to avoid collisions, stuff like that.</li>
<li>Hybrid planning - trying to solve for the different types of problems that an arm might need to solve (writing with chalk versus avoiding a collision with a surprise obstacle, for instance).</li>
<li>Definitely worth just digging through these slides/video in their/its entirety - no way I'm gonna be able to summarize this in text form (lot's of good diagrams/visuals).</li>
<li>"Chicken egg" problem of hardware integration: need hardware support to drive ROS2 adoption, need ROS2 adoption to drive hardware support</li>
<li>micro-ROS - interesting project to work with microcontrollers on ROS, glad to see this getting attached to other projects like MoveIt</li>
<li>Next stage: fully leverage ROS 2
<ul>
<li>ROS 2 release every 6 weeks</li>
<li>Main branch switching to Rolling Ridley</li>
</ul>
</li>
</ul>
</li>
<li>Talk about calibrating a robot arm using a camera
<ul>
<li>2 forms: eye to hand, and eye in hand
<ul>
<li>Really more or less the same problem</li>
</ul>
</li>
<li>Lots of transforms and math</li>
<li>I'mma need to brush up on my linear algebra</li>
<li>AX=XB solvers - there's a bunch of solutions for this problem, including OpenCV</li>
<li>Live demo is a simulation, because the robot is broken - classic</li>
<li>I will note, RVIZ is a lot less ugly now.</li>
</ul>
</li>
<li>Robot Assembly Presentation
<ul>
<li>Presenter from Omron</li>
<li>World Robot Summit Assembly Challenge</li>
<li>Challenge: build component with lots of small parts and fine motor control required</li>
<li>Traditional solution: lots of custom jigs and machining, separate everything into simple tasks</li>
<li>Very expensive!</li>
<li>Omron solution:
<ul>
<li>"Connecting a lot of things together -- ROS helps"</li>
<li>"Always strike a balance between prototyping speed and machine control"</li>
<li>"Sliding scale of complexity" to existing approaches</li>
<li>Really in-depth here, definitely good stuff if you're interested in this kind of repeatable autonomous fine manipulation with end effectors</li>
<li>Pretty cool collaboration between two robot arms shown</li>
<li>Emphasis on robustness</li>
</ul>
</li>
</ul>
</li>
<li>Constraint-based Cartesian Planning
<ul>
<li>Task constraints: how tools and such are allowed to move</li>
<li>Generally expect cartesian planning to "just work"</li>
<li>Number of different options for planning cartesian movement, all with trade-offs</li>
<li>OMPL Constraint Planning - Summer of Code project
<ul>
<li>Used to plan NASA's Robonaut 2</li>
<li>Need to replace existing "PoseModel" which has issues - joint space jumps and such</li>
<li>Lots of high quality gifs</li>
<li>Sampling-based motion planning - interesting approach to find valid and invalid poses</li>
</ul>
</li>
</ul>
</li>
<li>Robonaut 2 from NASA
<ul>
<li>Cool multi-armed robot that moves in zero-gravity on space station</li>
<li>Lots of path-planning, control challenges arise when trying to use arms to pull yourself around a tiny space capsule</li>
<li>TaskForce - tool to help task-based motion planning
<ul>
<li>Makes MoveIt control easier and more versatile</li>
</ul>
</li>
<li>Currently open sourcing both tools</li>
</ul>
</li>
<li>MoveIt Capabilities Overview
<ul>
<li>Good roll at the end showing all the different use-cases for MoveIt. Honestly, should've led with that.</li>
</ul>
</li>
</ul>
<h2 id="%E2%9A%A1-lightning-talks-3" tabindex="-1">⚡ Lightning Talks 3</h2>
<p>Had to come back for this one.</p>
<ul>
<li>PlotJuggler 3.0
<ul>
<li>+1 for most interesting man in the world meme.</li>
<li>Pretty good stuff from a data vis perspective, nice hooks into the ROS tooling</li>
<li>Window system reminds me of Visual Studio</li>
<li>Meme dunking on Matlab. Outstanding</li>
<li><a href="https://plotjuggler.io/">plotjuggler.io</a></li>
</ul>
</li>
<li>GurumNetworks ad
<ul>
<li>High production quality, low calorie content</li>
<li>"Best DDS"</li>
</ul>
</li>
<li>Intel OPENVINO Toolkit ad
<ul>
<li>Pictures = ton of data</li>
<li>Enables "Smart video and visualizations"</li>
<li>CV/Deep learning solution</li>
<li>Really throwing the kitchen sink of buzzwords</li>
</ul>
</li>
<li>Microsoft Ad
<ul>
<li>ROS on windows - 100000+ downloads</li>
<li>Lots of integrations</li>
<li>Ooh, Mixed Reality Toolkit for ROS2 (mispelled in the slide, oops) - that's pretty exciting</li>
</ul>
</li>
<li>Zebracorns FRC Team 900
<ul>
<li>First Robotics Competition</li>
<li>Bringing ROS to FRC</li>
<li>Pretty wild output from Highschoolers. Good for them!</li>
</ul>
</li>
<li>RobotIS
<ul>
<li>Turtlebot3!</li>
<li>Lots of fun consumer/industrial robotics showcasing happening here, very quickly.</li>
</ul>
</li>
<li>Auterion
<ul>
<li>Autonomous Drone Flight Controller</li>
<li>Also includes other mobile robots?</li>
<li>Skynode</li>
<li>Sharp polos</li>
<li>Why doesn't this guy have a polo?</li>
</ul>
</li>
<li>SICK Sensor Intelligence
<ul>
<li>"Industry 4.0" ugh</li>
<li>Warehouse robotics solution</li>
</ul>
</li>
</ul>
<h2 id="%F0%9F%93%95-closing-remarks---ryan-gariepy" tabindex="-1">📕 Closing Remarks - Ryan Gariepy</h2>
<ul>
<li>Ryan Gariepy, CTO Clearpath/OTTO Motors</li>
<li>1.5 Megatons of CO2 saved by being online</li>
<li>More participants then ever before (maybe because it's free?)</li>
<li>Lot of US attendees, but also from around the world</li>
<li>Many thanks to many sponsors</li>
<li>Roberta Friedman - Founder and CFO of Open Robotics, is retiring</li>
<li>Videos should be up by weekend</li>
<li>Survey coming soon</li>
<li>ROSCon 2021 October 19th-24th, in New Orleans</li>
</ul>
<h2 id="%E2%9A%A1-lightning-talks-4" tabindex="-1">⚡ Lightning Talks 4</h2>
<ul>
<li>Webots Robot Simulator
<ul>
<li>Lots of premade robots to simulate</li>
<li>Graphical Editor</li>
<li>ROSin support</li>
</ul>
</li>
<li>Weekly Robotics
<ul>
<li>Mat Sadowski does a great job with this weekly newsletter! Big fan of this guy's work. Check it out <a href="https://weeklyrobotics.com/">here</a></li>
</ul>
</li>
<li>Technaid S.L.
<ul>
<li>H3 Exoskeleton</li>
<li>A ROS compatible exoskeleton? Neat!</li>
<li>Definitely makes security seem really important</li>
</ul>
</li>
<li>ROS Industrial
<ul>
<li>Ben Greenberg</li>
<li>ROS is intimidating for newbies - fair</li>
<li>Web-based tools for less technical users</li>
<li>3D viewer</li>
<li>WebVis interface and terminal emulator</li>
<li>Mobile Friendly</li>
</ul>
</li>
<li>ROS for Robot Swarms
<ul>
<li>Phd Candidate(?) showing off swarm collaboration</li>
<li>Swarm Mapping</li>
<li>Swarm monitoring</li>
</ul>
</li>
<li>Greenzie
<ul>
<li>Selfie cam, bold move</li>
<li>Lawn maintenance robots</li>
<li>Adapt electric lawn mowers to "Autostriping"</li>
<li>Lots of familiar tools and tech on here</li>
</ul>
</li>
<li>ROS for Autonomous Maritime Systems
<ul>
<li>UL Lafayette Engineering</li>
<li>The C.R.A.W. Lab - Outstanding pun.</li>
<li>Look at that boat go.</li>
<li>RoboBoat! Big fan.</li>
<li>Even smaller RoboBoat!</li>
</ul>
</li>
<li>MoveIt
<ul>
<li>Throwback to Omron's presentation from the MoveIt talk.</li>
</ul>
</li>
<li>Nobleo
<ul>
<li>Is that Sylvan Esso? No, just a similar bass line</li>
<li>Autonomous Pallet Jacks (Terrifying, to anyone who's ever taken one to the ankle before).</li>
<li>More Digital Twins</li>
</ul>
</li>
</ul>