<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nathaniel Handan</title>
    <description>The latest articles on DEV Community by Nathaniel Handan (@tinnyrobot).</description>
    <link>https://dev.to/tinnyrobot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1040863%2F7d1161ee-2e10-4c7b-a2f2-2745739d772f.jpg</url>
      <title>DEV Community: Nathaniel Handan</title>
      <link>https://dev.to/tinnyrobot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tinnyrobot"/>
    <language>en</language>
    <item>
      <title>94 Million Hausa Speakers, and AI Still Barely Understands Them. What Three Years of Grassroots Work Taught Me.</title>
      <dc:creator>Nathaniel Handan</dc:creator>
      <pubDate>Sat, 25 Jul 2026 07:05:27 +0000</pubDate>
      <link>https://dev.to/tinnyrobot/94-million-hausa-speakers-and-ai-still-barely-understands-them-what-three-years-of-grassroots-4hob</link>
      <guid>https://dev.to/tinnyrobot/94-million-hausa-speakers-and-ai-still-barely-understands-them-what-three-years-of-grassroots-4hob</guid>
      <description>&lt;p&gt;Hausa is spoken by close to 94 million people in Nigeria alone, with tens of millions more across Niger and the wider Sahel. Nature has reported that ChatGPT and LLMs correctly understands only 10 to 20 percent of sentences written in Hausa.&lt;/p&gt;

&lt;p&gt;I've spent the last three years trying to close that gap. First alone, then with a community I founded in Bauchi State that's since grown past 500 people. This isn't really a project retrospective. It's an honest account of what it actually takes to build language technology for a language the industry has quietly decided isn't worth the training data, and what leading the people doing that work with me has taught me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the gap exists, and why scraping the web won't fix it
&lt;/h2&gt;

&lt;p&gt;The easy explanation for Hausa's AI gap is "not enough data." That's true, but it undersells the problem. Hausa has technical properties that make naive data collection actively misleading, not just insufficient.&lt;/p&gt;

&lt;p&gt;Start with orthography. Standard written Hausa uses three hooked consonants, ɓ, ɗ, and ƙ, that don't exist on a standard keyboard. In formal, edited text they're there. In the informal Hausa that actually dominates the web (social media, SMS, WhatsApp, the actual keyboards people type on) they're routinely flattened to plain b, d, and k. Scrape the open web for Hausa and you get a corpus quietly missing phonemic information in a large share of its examples, and that gap propagates into anything trained on it, from tokenizers to text to speech models.&lt;/p&gt;

&lt;p&gt;Then there's script. Hausa has been written in two systems for over a century: Boko, the Latin based script that's now standard, and Ajami, an Arabic based script still used in religious and literary contexts. A dataset built only from Boko sources is already excluding a real slice of the written language.&lt;/p&gt;

&lt;p&gt;Then code-switching. Everyday Hausa, especially online, mixes in English freely and carries a long history of Arabic loanwords from Islamic scholarly tradition. A model that treats Hausa as a clean, isolated language misses how the language is actually used in practice.&lt;/p&gt;

&lt;p&gt;Put those together and "low-resource language" starts to look less like "not enough Hausa exists" and more like "the Hausa that's easy to scrape is a degraded sample of the Hausa people actually speak." Standard multilingual tokenizers, trained on that same degraded sample, fragment Hausa words into far more subword pieces than an equivalent English sentence needs. That makes inference more expensive and generation noticeably worse, since the model has fewer clean examples to learn from per token.&lt;/p&gt;

&lt;p&gt;That's the actual problem. Not "AI doesn't know Hausa." AI has been fed a thin, flattened version of Hausa, and it shows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I actually started, and why not with an LLM
&lt;/h2&gt;

&lt;p&gt;I founded AI Bauchi in October 2022 out of Abubakar Tafawa Balewa University, with a mission that hasn't changed since day one: make AI indigenous and accessible in Bauchi State, not just consumed from outside it. The language work grew out of that mission, not the other way around.&lt;/p&gt;

&lt;p&gt;The tempting move, and the one I've watched well-funded initiatives make, is to announce a "Hausa LLM" on day one. I didn't do that, and I don't think a volunteer community should. A full generative language model needs enormous clean data and compute to be worth the name. What a community of volunteers with day jobs and a group chat actually has is time, native speaker knowledge, and the ability to ship something narrow and useful while the harder foundation gets built underneath it.&lt;/p&gt;

&lt;p&gt;So the sequence was deliberate. A Hausa text to speech model first, because it forces you to solve the orthography and pronunciation problem directly. A Hausa to Sayawa translator alongside it, because it forces the team to think about Hausa in relation to another indigenous language instead of only English. A media processing library, HausaMediaLab, that turns both into something a developer outside the project can actually pull in and use. Each of those was scoped to ship, not to impress. Each also produces cleaner labeled data as a byproduct, which is exactly the fuel a more ambitious language model eventually needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that's actually hard: building a team that isn't just engineers
&lt;/h2&gt;

&lt;p&gt;Here's the decision I'd defend hardest to another technical lead: the TTS project's contributors aren't only machine learning engineers. They're ML engineers, data scientists, linguists, and software developers, working together on purpose.&lt;/p&gt;

&lt;p&gt;That's not a diversity nicety, it's an engineering requirement. An ML engineer can build a text to speech pipeline. An ML engineer without a linguist on the team will get tone marking and hooked consonants subtly wrong in ways that are invisible to anyone who doesn't speak the language natively, and obvious to everyone who does.&lt;/p&gt;

&lt;p&gt;There's a second representation question underneath that one: which Hausa. The language spans real dialectal variation. The Kano variety often treated as a reference standard is not the only lived version of the language, and a single synthetic voice trained on one region's speech quietly tells everyone else their Hausa is the deviation. A linguist in the room is what catches that before it ships, not after.&lt;/p&gt;

&lt;p&gt;So the structure is: weekly progress meetings, native speakers reviewing linguistic decisions, engineers reviewing the model, and a public repo with issues explicitly tagged for newcomers so the contributor pipeline doesn't dry up when the founding few get busy. Alongside the language projects we run bootcamps, an eleven week AI bootcamp and a six week computer vision bootcamp, that exist specifically to grow that pipeline. Most contributors to the harder projects came up through one of those cohorts first.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like outside the repository
&lt;/h2&gt;

&lt;p&gt;If I only talked about the model, I'd be underselling what actually moved. A few things I'd point to as the real impact:&lt;/p&gt;

&lt;p&gt;I spent six months in 2023 as an instructor for NITDA's AI Developer Training, which meant the ideas driving AI Bauchi's work weren't staying inside one community, they were reaching a national training cohort. At DevFest Bauchi 2023 I gave a talk called "Democratizing Indigenous AI," making the case to a room of general developers, most of whom had never thought about Hausa specifically, that inclusive AI development has to start by respecting the linguistic and cultural nuance of the communities it claims to serve. In 2025 we ran EmpowerHer AI Bauchi, built to get more young women into this pipeline early, because a community that only recruits people who already see themselves as engineers keeps producing the same blind spots. And we've taken this outside the university entirely, hosting secondary school students from I-Scholars International Academy for a STEM excursion at NCAIR, Nigeria's National Centre for Artificial Intelligence and Robotics, because the earliest point to fix "who gets to build this" is before someone's chosen a degree.&lt;/p&gt;

&lt;p&gt;None of that shows up in a commit history. All of it is why the commit history exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this sits next to the bigger picture
&lt;/h2&gt;

&lt;p&gt;In 2025, Nigeria's federal government unveiled its own multilingual model effort through NITDA and NCAIR, covering Hausa alongside Yoruba and Igbo. That's a good thing, and it's an enormous, well-funded validation of a problem AI Bauchi had already been working on, in public, since 2023.&lt;/p&gt;

&lt;p&gt;I don't think grassroots work like ours competes with that kind of national effort. I think it's what keeps it honest. A federally funded model can move fast and cover a lot of ground. A community-built one, with linguists in the room and native speakers reviewing every tone mark, is what makes sure the fast version doesn't flatten the same nuance the open web already flattened. Both are needed. I'd rather our work be the thing that keeps the bigger effort accountable than the thing racing it for a headline.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note to self before publishing:&lt;/strong&gt; I want this section grounded in exactly what I used, not a general gesture at the program. Naming the actual services, credits, or mentorship conversations that fed into this work is also the part AWS reviewers will check most closely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What being an AWS Community Builder actually gave this
&lt;/h2&gt;

&lt;p&gt;The program's value to this work was never the swag. It was mentorship conversations with AWS specialists who'd already thought hard about deploying models into low connectivity, resource constrained environments, which is the exact condition Bauchi operates under, and credits that let a volunteer community run experiments it couldn't otherwise afford. S3, GPU training instances of Sagemaker&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell another builder trying this in their own community
&lt;/h2&gt;

&lt;p&gt;Start narrower than feels ambitious. A translator or a TTS model that ships is worth more than a language model that stays a roadmap item. Recruit people who aren't engineers before you think you need them, because by the time you obviously need a linguist, you've already shipped something linguistically wrong. Treat your constraints, low connectivity, volunteer time, no enterprise compute budget, as a design spec, not an excuse. Some of the most careful data hygiene decisions in this project exist specifically because we couldn't afford to throw compute at a sloppy dataset the way a better funded team might.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this goes next
&lt;/h2&gt;

&lt;p&gt;The text to speech model and the translator were never the destination. They were how a volunteer community earns the right to attempt something bigger, and that bigger thing is still the goal. If you're building language technology for a community that big tech has decided isn't worth the training data, or you're an AWS Community Builder working in a similarly underserved region or language, I'd genuinely like to compare notes. Drop a comment, or find AI Bauchi and say hello.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>aws</category>
    </item>
    <item>
      <title>Cloud Robotics Development on AWS: Migrating from RoboMaker to Batch</title>
      <dc:creator>Nathaniel Handan</dc:creator>
      <pubDate>Thu, 18 Sep 2025 10:46:55 +0000</pubDate>
      <link>https://dev.to/tinnyrobot/cloud-robotics-development-on-aws-migrating-from-robomaker-to-batch-35gn</link>
      <guid>https://dev.to/tinnyrobot/cloud-robotics-development-on-aws-migrating-from-robomaker-to-batch-35gn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Traditional local robotics simulation (e.g. running Gazebo on a laptop or on-prem server) can be limited by hardware resources and parallelism. AWS &lt;strong&gt;RoboMaker&lt;/strong&gt; was launched to simplify cloud-based robotics development: it provided a fully managed service for ROS/Gazebo simulations, with built-in container images, random world generation (WorldForge), and integration with cloud services (e.g. Kinesis, CloudWatch) via ROS packages&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=RoboMaker%20cloud%20extensions%20for%20ROS,in%20a%20familiar%20software%20framework" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;. RoboMaker enabled automated scaling of compute for simulation workloads (“fully managed…scales underlying infrastructure”&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=AWS%20RoboMaker%20provides%20a%20fully,the%20use%20cases%20above%20is" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;) and offered both headless and GUI (NICE DCV) simulation modes. However, AWS has announced that &lt;strong&gt;RoboMaker will be discontinued on September 10, 2025&lt;/strong&gt;&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html#:~:text=End%20of%20support%20notice%3A%20On,simulations%2C%20visit%20this%20blog%20post" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;. After that date, the RoboMaker console and APIs will no longer be available, and all simulation workloads must be migrated to alternatives – principally &lt;strong&gt;AWS Batch&lt;/strong&gt;, AWS’s general-purpose batch compute service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx13un3gisbsfmfttzt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx13un3gisbsfmfttzt9.png" alt=" " width="643" height="661"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure: Example RoboMaker simulation architecture – two containers (a simulation app with NVIDIA Isaac Sim and a robot app with ROS2 Navigation) orchestrated by AWS RoboMaker, pulling images from Amazon ECR and outputting logs to CloudWatch.&lt;/p&gt;

&lt;p&gt;AWS Batch provides a container-based, highly scalable batch job scheduler. In contrast to RoboMaker’s robotics-specific interface, Batch requires users to define their own Docker images and compute environments, but offers flexibility and massive scale (including multi-container and multi-node parallel jobs). As AWS notes, &lt;strong&gt;“AWS Batch is best used for running headless batch simulations at scale”&lt;/strong&gt;, whereas interactive GUI simulations were a RoboMaker feature&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Note%20that%20AWS%20Batch%20is,we%20recommend%20AWS%20RoboMaker%20simulation" rel="noopener noreferrer"&gt;[5]&lt;/a&gt;. In practice, migrating to Batch means converting RoboMaker simulation workflows into a containerized CI/CD pipeline on Batch: containerize ROS/Gazebo apps, push images to ECR, define Batch compute environments and jobs, and orchestrate execution. This guide lays out the detailed migration path, compares features of RoboMaker vs Batch, and provides examples and best practices for setting up cloud robotics simulation on AWS Batch.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RoboMaker sunset:&lt;/strong&gt; AWS RoboMaker ends Sep 2025&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html#:~:text=End%20of%20support%20notice%3A%20On,simulations%2C%20visit%20this%20blog%20post" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;. All existing simulation apps, worlds, and jobs must be migrated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strategy:&lt;/strong&gt; Move to AWS Batch: export any RoboMaker-generated assets (worlds, models), containerize your robot and simulation code (ROS2 Humble + Gazebo + TurtleBot3) into Docker images, push to ECR, then create AWS Batch compute environments, job queues, and job definitions to run those containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architectural shift:&lt;/strong&gt; RoboMaker managed infrastructure and had built-in simulation tools; Batch is generic compute. You lose integrated features (e.g. worldforge GUI, on-demand development IDE) but gain control of instance types, unlimited scaling, and cost optimization (no Batch service fee&lt;a href="https://aws.amazon.com/batch/pricing/#:~:text=There%20is%20no%20additional%20charge,Discounts%20will" rel="noopener noreferrer"&gt;[6]&lt;/a&gt;, Spot instances, multi-node jobs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step-by-step:&lt;/strong&gt; (1) Export worlds/models from RoboMaker (via WorldForge ZIP to S3)&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/worlds-using-export-simulation.html#:~:text=With%20Simulation%20WorldForge%2C%20you%20can,an%20exported%20world%20in%20an" rel="noopener noreferrer"&gt;[7]&lt;/a&gt;. (2) Build Docker images for your robot app and sim app (use &lt;code&gt;osrf/ros:humble-desktop&lt;/code&gt; or Ubuntu base, install TurtleBot3 packages and Gazebo). (3) Push images to ECR. (4) Set up AWS Batch: create a Compute Environment (choose EC2/Spot instances for CPU/GPU), a Job Queue linked to it, and a Job Definition specifying the Docker image, vCPU/memory, commands, and environment variables. (5) Submit and run Batch jobs (single-node or multi-node as needed) to execute your simulations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost &amp;amp; scaling:&lt;/strong&gt; Unlike RoboMaker’s per-job pricing model, AWS Batch has &lt;em&gt;no extra charge&lt;/em&gt; – you pay only for EC2 (or Fargate) resources&lt;a href="https://aws.amazon.com/batch/pricing/#:~:text=There%20is%20no%20additional%20charge,Discounts%20will" rel="noopener noreferrer"&gt;[6]&lt;/a&gt;. Use Spot for cheaper compute. Batch easily scales to hundreds or thousands of concurrent jobs (RoboMaker was limited to 10 concurrent sims by default&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=,an%20increase%20in%20this%20limit" rel="noopener noreferrer"&gt;[8]&lt;/a&gt;). Headless (non-GUI) simulations run on plain CPU/GPU instances; GUI/CDV sessions (rare in Batch) require custom setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring &amp;amp; automation:&lt;/strong&gt; Continue using CloudWatch for logs and metrics (e.g. ROS position/sensor data stream)&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Amazon%20CloudWatch%20robot%20monitoring%20sample,the%20robot%E2%80%99s%20position%20and%20speed" rel="noopener noreferrer"&gt;[9]&lt;/a&gt;. Store inputs/outputs and world files in S3. You can orchestrate workflows with AWS Step Functions or CodePipeline, similarly to RoboMaker pipelines&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=Launch%20in%20GitHub" rel="noopener noreferrer"&gt;[10]&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Feature &amp;amp; Architecture Comparison: RoboMaker vs AWS Batch
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service model:&lt;/strong&gt; RoboMaker is a specialized managed robotics service. It abstracts away servers and networks, providing a GUI for launching simulation jobs&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=AWS%20RoboMaker%20provides%20a%20fully,the%20use%20cases%20above%20is" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;. Batch is a generic container batch scheduler (built on ECS/EKS and EC2). You &lt;strong&gt;must&lt;/strong&gt; provision Compute Environments and define job resources yourself. RoboMaker auto-creates instances behind the scenes; Batch lets you control instance types (CPU vs GPU, on-demand vs Spot) and autoscaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workload support:&lt;/strong&gt; RoboMaker is built for ROS/Gazebo robot simulation. It used to offer prebuilt Docker images for ROS1/2 and Gazebo (though now customers must supply container images)&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html#:~:text=End%20of%20support%20notice%3A%20On,simulations%2C%20visit%20this%20blog%20post" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/pdfs/robomaker/latest/dg/aws-robomaker-dg.pdf#:~:text=AWS%20RoboMaker%20Developer%20Guide%20End,xi" rel="noopener noreferrer"&gt;[11]&lt;/a&gt;. It introduced concepts of &lt;em&gt;Robot applications&lt;/em&gt; (the code running on a robot) and &lt;em&gt;Simulation applications&lt;/em&gt; (the Gazebo world and scenario). AWS Batch can run &lt;strong&gt;any&lt;/strong&gt; Linux container. You can build ROS2/Gazebo containers and run them on Batch, but there is no built-in “robot vs simulation app” distinction unless you implement it (e.g. separate containers or processes). Notably, AWS Batch now supports &lt;strong&gt;multi-container jobs&lt;/strong&gt; (started Apr 2024)&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=Recently%2C%20AWS%20Batch%20launched%20a,collaboration%2C%20and%20other%20advanced%20simulations" rel="noopener noreferrer"&gt;[12]&lt;/a&gt;: you can run multiple cooperating containers (e.g. one for Gazebo sim, others for different robot sensor pipelines) within a single Batch job. This enables modular simulation setups similar to RoboMaker’s multi-robot examples (see figure below)&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=runner%2C%20the%20simulation%20app%2C%20and,lidar%2C%20vision%20processing%20and%20control" rel="noopener noreferrer"&gt;[13]&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; RoboMaker allowed batching many simulation jobs via the BatchSimulation API, but had limits (default max 10 concurrent jobs)&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=,an%20increase%20in%20this%20limit" rel="noopener noreferrer"&gt;[8]&lt;/a&gt;. It scaled each job’s infrastructure automatically, but overall batch size was constrained by quotas. AWS Batch scales to as many parallel jobs as you request (limited only by account quotas and budget). It also supports &lt;strong&gt;multi-node parallel jobs&lt;/strong&gt; for distributed simulations (for example, spread 4 robots across 4 EC2 nodes). In practice, Batch can run hundreds or thousands of simulations in parallel easily. RoboMaker’s underlying hardware limits were lower and fixed per job (e.g. one c5.2xlarge per simulation, 4 vCPU/32GB by default). On Batch you choose any instance sizes you need (e.g. high-CPU c6i, GPU g4dn, or even the new inf series), and use Spot capacity for cost efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headless vs GUI:&lt;/strong&gt; RoboMaker supported both headless (no X-windows) and interactive GUI simulations via NICE DCV, which allowed streaming the Gazebo/ROS GUI remotely. AWS Batch is designed for &lt;strong&gt;headless&lt;/strong&gt; batch processing&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Note%20that%20AWS%20Batch%20is,we%20recommend%20AWS%20RoboMaker%20simulation" rel="noopener noreferrer"&gt;[5]&lt;/a&gt;. It can run GUI apps in containers (you can even run NICE DCV servers on GPU instances under Batch), but it doesn’t provide the interactive console integration that RoboMaker did. In migration you will likely run Gazebo in headless mode (gzserver only) and collect data/metrics, rather than interact with a live 3D view. Batch is optimized for “thousands of scenarios” at once&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Headless%20robotic%20simulations%20with%20AWS,what%20compute%20types%20to%20use" rel="noopener noreferrer"&gt;[14]&lt;/a&gt;, not manual GUI sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud services integration:&lt;/strong&gt; RoboMaker included ROS cloud extensions out of the box: packages for streaming video (Kinesis Video Streams), vision inference (Rekognition), voice (Lex/Polly), and metrics/logging (CloudWatch)&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=RoboMaker%20cloud%20extensions%20for%20ROS,in%20a%20familiar%20software%20framework" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;. These let robot code easily call AWS services. In AWS Batch, you lose that built-in convenience layer, but you &lt;em&gt;can&lt;/em&gt; still use the same AWS services by invoking SDKs or passing through Step Functions. For example, you can publish ROS data to CloudWatch logs or metrics exactly as before&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Amazon%20CloudWatch%20robot%20monitoring%20sample,the%20robot%E2%80%99s%20position%20and%20speed" rel="noopener noreferrer"&gt;[9]&lt;/a&gt;, just handled by your container code. Batch itself does not impose an additional fee – you pay only for the EC2/Fargate resources you use&lt;a href="https://aws.amazon.com/batch/pricing/#:~:text=There%20is%20no%20additional%20charge,Discounts%20will" rel="noopener noreferrer"&gt;[6]&lt;/a&gt;, whereas RoboMaker charged by simulation time. Batch supports IAM roles for tasks, VPC networking, and can integrate with S3, EFS, CloudWatch, Step Functions, etc., just like any other AWS compute environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Export simulation assets:&lt;/strong&gt; Use RoboMaker’s WorldForge export or manual methods to extract any custom world files, models, or assets you used. RoboMaker can package generated worlds into a ZIP and drop it in S3&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/worlds-using-export-simulation.html#:~:text=With%20Simulation%20WorldForge%2C%20you%20can,an%20exported%20world%20in%20an" rel="noopener noreferrer"&gt;[7]&lt;/a&gt;. Download these files or point to their S3 locations for use in your Docker images or batch jobs. Likewise, retrieve any logs or output data from past RoboMaker runs for reference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containerize applications:&lt;/strong&gt; Build Docker images for your robot and simulation code. For example, start from an official ROS2 Humble base (e.g. &lt;code&gt;osrf/ros:humble-desktop&lt;/code&gt;), install Gazebo (Fortress) and TurtleBot3 packages (&lt;code&gt;ros-humble-turtlebot3&lt;/code&gt;*), and copy your ROS workspace in. A sample Dockerfile snippet might look like:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ros:humble-ros-base&lt;/span&gt;

&lt;span class="c"&gt;# Set environment variables&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ROS_DISTRO=humble&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; TURTLEBOT3_MODEL=burger&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-desktop &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-turtlebot3-gazebo &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-turtlebot3-description &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-gazebo-ros-pkgs &lt;span class="se"&gt;\
&lt;/span&gt;    gazebo11 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Copy your workspace&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./simulation_ws /home/ros_ws&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /home/ros_ws&lt;/span&gt;

&lt;span class="c"&gt;# Build the workspace&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"source /opt/ros/&lt;/span&gt;&lt;span class="nv"&gt;$ROS_DISTRO&lt;/span&gt;&lt;span class="s2"&gt;/setup.bash &amp;amp;&amp;amp; colcon build"&lt;/span&gt;

&lt;span class="c"&gt;# Source both ROS and workspace overlays&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/bin/bash", "-c", \&lt;/span&gt;
    "source /opt/ros/$ROS_DISTRO/setup.bash &amp;amp;&amp;amp; \
     source /home/ros_ws/install/setup.bash &amp;amp;&amp;amp; \
     ros2 launch my_sim_pkg simulate.launch.py"]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Modify the &lt;code&gt;ENTRYPOINT&lt;/code&gt; or &lt;code&gt;CMD&lt;/code&gt; to start your simulation (headless). You can create separate images for the robot-app and sim-app if needed, but with Batch’s multi-container support you can also launch multiple containers from one job. Push these images to Amazon ECR (or any container registry)&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=2,app%60%20respectively" rel="noopener noreferrer"&gt;[15]&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prepare Batch environment:&lt;/strong&gt; In the AWS Console (or via CloudFormation/CLI), create a &lt;strong&gt;Compute Environment&lt;/strong&gt; for AWS Batch. Choose EC2 (or Fargate) and select instance types needed (e.g., c6i.large for CPU sims, &lt;code&gt;g4dn.xlarge&lt;/code&gt; for GPU-enabled Gazebo). Consider using Spot instances for cost savings, since simulation workloads are interruptible. Attach an IAM instance role that allows pulling from ECR and writing to S3/CloudWatch. Create a &lt;strong&gt;Job Queue&lt;/strong&gt; and associate it with this compute environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define Batch jobs:&lt;/strong&gt; Create an AWS Batch &lt;strong&gt;Job Definition&lt;/strong&gt;. Specify &lt;code&gt;"type": "container"&lt;/code&gt; and in &lt;code&gt;containerProperties&lt;/code&gt; include: your Docker image URI (from ECR), vCPU count and memory, and the command to run (e.g. [&lt;code&gt;"ros2"&lt;/code&gt;, &lt;code&gt;"launch"&lt;/code&gt;, &lt;code&gt;"my_sim_pkg"&lt;/code&gt;, &lt;code&gt;"simulate.launch.py"&lt;/code&gt;]). Add any environment variables (e.g. &lt;code&gt;TURTLEBOT3_MODEL=burger&lt;/code&gt;). For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobDefinitionName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turtlebot3-sim-job"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"container"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"containerProperties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123456789012.dkr.ecr.us-west-2.amazonaws.com/turtlebot3-sim:latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vcpus"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"memory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TURTLEBOT3_MODEL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"burger"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jobRoleArn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/BatchJobRole"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the AWS Batch console or &lt;code&gt;RegisterJobDefinition&lt;/code&gt; API. Ensure the &lt;code&gt;jobRoleArn&lt;/code&gt; has permissions for any AWS calls (CloudWatch, S3). If your simulation needs shared storage (e.g. large maps or logging folders), you can configure EFS volumes in the job or let the container fetch from S3 at startup.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Multi-node or multi-container (optional):&lt;/strong&gt; For advanced scenarios (e.g. multi-robot swarms or separate sensor modules), use Batch’s &lt;strong&gt;Multi-Node Parallel (MNP)&lt;/strong&gt; jobs or multi-container job feature. MNP allows you to run a single job across multiple EC2 instances. Multi-container jobs (containers sharing a local network on the same node) enable separate processes for e.g. Gazebo, lidar processing, control, etc. This was not possible in RoboMaker (which ran all code in one container), but Batch now supports it&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=Recently%2C%20AWS%20Batch%20launched%20a,collaboration%2C%20and%20other%20advanced%20simulations" rel="noopener noreferrer"&gt;[12]&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring &amp;amp; logs:&lt;/strong&gt; Configure your containers to send output to STDOUT/STDERR so AWS Batch will push logs to CloudWatch Logs by default. For more detailed robot metrics, use ROS CloudWatch packages – e.g. send robot positions or sensor stats to CloudWatch Metrics as in the AWS sample&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Amazon%20CloudWatch%20robot%20monitoring%20sample,the%20robot%E2%80%99s%20position%20and%20speed" rel="noopener noreferrer"&gt;[9]&lt;/a&gt;. Set up a CloudWatch log group for your batch jobs. (RoboMaker automatically aggregated logs, but in Batch you manage the logging setup.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run and iterate:&lt;/strong&gt; Submit a Batch job (via Console, AWS CLI &lt;code&gt;submit-job&lt;/code&gt;, or through Step Functions). Watch CloudWatch for logs to debug. Tweak your Docker image or job definition if needed. Once a single robot sim works, you can scale up: run many Batch jobs in parallel (AWS Batch will queue them and launch on available EC2 instances).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate workflows:&lt;/strong&gt; To orchestrate batch simulations (for example, sweeping over parameters or training RL policies), use AWS Step Functions or CodePipeline. AWS even published a RoboMaker &lt;em&gt;Sample&lt;/em&gt; showing a pipeline for launching simulation batches&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=Launch%20in%20GitHub" rel="noopener noreferrer"&gt;[10]&lt;/a&gt; – you can adapt this by having Step Functions call &lt;code&gt;SubmitJob&lt;/code&gt; on AWS Batch instead. For CI/CD, put your Docker build and Batch job submission into a CodePipeline or GitHub Actions workflow.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cost and Performance Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pricing model:&lt;/strong&gt; AWS Batch itself is free – you only pay for the EC2/Fargate resources you use&lt;a href="https://aws.amazon.com/batch/pricing/#:~:text=There%20is%20no%20additional%20charge,Discounts%20will" rel="noopener noreferrer"&gt;[6]&lt;/a&gt;. RoboMaker charged per simulation-second at fixed hardware size, which could be expensive for large batches. With Batch, you can use Spot Instances for dramatic savings (up to 90% off) on fault-tolerant sims. You also control instance size: e.g. use 4 vCPU machines for a light TurtleBot sim, or 32 vCPU/8 GPU instances for a heavy physics simulation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling:&lt;/strong&gt; RoboMaker allowed parallel simulation but was capped by quotas (default 10 concurrent jobs&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=,an%20increase%20in%20this%20limit" rel="noopener noreferrer"&gt;[8]&lt;/a&gt;) and by its internal resource limits. AWS Batch can scale to hundreds of parallel jobs as long as you request it; there’s no per-job vCPU cap. Batch’s multi-node jobs also let you simulate many robots or heavy compute tasks in one coordinated job. For example, you could run a 4-robot warehouse sim on a 4-node MNP job (one robot per EC2) – something RoboMaker could not natively do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headless vs GUI:&lt;/strong&gt; AWS Batch is designed for &lt;strong&gt;headless&lt;/strong&gt; processing. If you need a real-time GUI (NICE DCV) you must provision GPU instances with desktop streaming yourself. In most robotics dev, you run Gazebo headless and record data for later analysis. RoboMaker’s ease of GUI was convenient for debugging, but came at higher cost (always requiring at least one GPU server). On Batch, you would typically run the same Gazebo world without gzclient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput &amp;amp; latency:&lt;/strong&gt; On similar instance types, raw simulation performance is comparable between RoboMaker and Batch (both run on AWS EC2 under the hood). However, Batch can batch-launch many instances quickly, whereas RoboMaker needed to spin up each sim job separately. This means large experiments (e.g. 1000 Monte Carlo sim runs) will complete faster on Batch. RoboMaker also introduced a concept of “simulation unit” (1 unit = 1 vCPU &amp;amp; 2GB RAM) to rate-limit usage, which Batch does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost example:&lt;/strong&gt; If you run a 4 vCPU/16GB sim for 1 hour, RoboMaker billed a fixed rate for that instance-hour. On AWS Batch you’d pay the on-demand (or Spot) EC2 rate for 4 vCPU for 1 hour. Using Spot can cut cost greatly for non-time-critical batches. Also, Batch allows scheduling interruptions or spot bids, whereas RoboMaker simply ran until the job finished or hit a limit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example AWS Batch Job Definition and Dockerfiles
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Example Dockerfile (ROS2 Humble + Gazebo + TurtleBot3):&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; osrf/ros:humble-desktop&lt;/span&gt;

&lt;span class="c"&gt;# Set environment variables&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ROS_DISTRO=humble&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; TURTLEBOT3_MODEL=burger&lt;/span&gt;

&lt;span class="c"&gt;# Install Gazebo and TurtleBot3 packages&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-turtlebot3-bringup &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-turtlebot3-gazebo &lt;span class="se"&gt;\
&lt;/span&gt;    ros-humble-gazebo-ros-pkgs &lt;span class="se"&gt;\
&lt;/span&gt;    gazebo11 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Copy simulation workspace&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./simulation_ws /home/ros_ws&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /home/ros_ws&lt;/span&gt;

&lt;span class="c"&gt;# Build the workspace&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"source /opt/ros/&lt;/span&gt;&lt;span class="nv"&gt;$ROS_DISTRO&lt;/span&gt;&lt;span class="s2"&gt;/setup.bash &amp;amp;&amp;amp; colcon build --symlink-install"&lt;/span&gt;

&lt;span class="c"&gt;# Create entrypoint script&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'#!/bin/bash\n&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s1"&gt;set -e\n&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s1"&gt;source /opt/ros/$ROS_DISTRO/setup.bash\n&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s1"&gt;source /home/ros_ws/install/setup.bash\n&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="s1"&gt;exec "$@"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /ros_entrypoint.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;chmod&lt;/span&gt; +x /ros_entrypoint.sh

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/ros_entrypoint.sh"]&lt;/span&gt;

&lt;span class="c"&gt;# Default command: launch TurtleBot3 world&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["ros2", "launch", "turtlebot3_gazebo", "turtlebot3_world.launch.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This image will launch a Gazebo world (&lt;code&gt;turtlebot3_world.launch.py&lt;/code&gt;) with TurtleBot3. Customize the workspace and launch files as needed. Build and push this image to ECR with a command like: &lt;code&gt;docker build -t turtlebot3-sim:latest .&lt;/code&gt; then &lt;code&gt;docker tag&lt;/code&gt; and &lt;code&gt;aws ecr create-repository&lt;/code&gt; &amp;amp; &lt;code&gt;aws ecr get-login-password&lt;/code&gt; to push.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example AWS Batch Job Definition (JSON):&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobDefinitionName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TurtleBot3SimulationJob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"container"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"containerProperties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123456789012.dkr.ecr.us-west-2.amazonaws.com/turtlebot3-sim:latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vcpus"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"memory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16384&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TURTLEBOT3_MODEL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"burger"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jobRoleArn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/BatchJobRole"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we allocate 4 vCPUs and 16 GB RAM for the sim, and pass the model type via env. Adjust vcpus/memory based on your workload. The &lt;code&gt;jobRoleArn&lt;/code&gt; should grant permissions to read/write any needed AWS resources (e.g. an S3 bucket for world files or log output, and CloudWatch access).&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring, Storage, and Automation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Monitoring:&lt;/strong&gt; Instrument your ROS nodes to publish metrics or log to CloudWatch as needed. AWS provides ROS &lt;em&gt;CloudWatch&lt;/em&gt; packages (as in the sample) so you can push robot state (position, velocity) and key events to CloudWatch Metrics or Logs&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Amazon%20CloudWatch%20robot%20monitoring%20sample,the%20robot%E2%80%99s%20position%20and%20speed" rel="noopener noreferrer"&gt;[9]&lt;/a&gt;. Since Batch runs on ECS underneath, each container’s STDOUT goes to CloudWatch Logs automatically, which you can view in real time for debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage (S3/EFS):&lt;/strong&gt; Use Amazon S3 for storing large assets: keep your exported world ZIPs and static models in an S3 bucket and download them at container startup (or bake them into the Docker image). Simulation outputs (e.g. rosbag files, CSV data) can be written back to S3 at job completion. For shared file-system needs (e.g. sharing a map or checkpoints across multiple Batch job runs), you can mount an Amazon EFS volume in your job definition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orchestration (Step Functions/CodePipeline):&lt;/strong&gt; For complex workflows (e.g. run simulation sweep, then train ML model on results, then run more sims), use AWS Step Functions to coordinate AWS Batch jobs. Step Functions has native support to start Batch jobs and wait for completion. AWS also provides sample pipelines (e.g. RoboMaker “Simulation launcher” using CodePipeline + Step Functions)&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=Launch%20in%20GitHub" rel="noopener noreferrer"&gt;[10]&lt;/a&gt; – you can adapt these so that Step Functions calls Batch instead of RoboMaker APIs. For example, a Step Function state machine could have a “Submit Simulation Job” task (using Action=Batch:SubmitJob) followed by a “Wait for Job” and condition based on job success. Similarly, CodePipeline can trigger a new Docker build and then invoke a Batch job via a Lambda step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging &amp;amp; Alerts:&lt;/strong&gt; Tag your Batch jobs with meaningful tags and set up CloudWatch alarms on metrics (e.g. if jobs are failing or if S3 buckets grow). You can also export Batch job metrics (queued/running counts) to CloudWatch for dashboards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these steps &lt;br&gt;
– exporting your assets, containerizing your apps, setting up AWS Batch compute and jobs, and integrating logging/automation &lt;br&gt;
– you can replicate and extend your RoboMaker simulations on AWS Batch. &lt;/p&gt;

&lt;p&gt;Although the transition requires more setup, Batch gives you much greater flexibility and cost control for large-scale robotics workloads. Leveraging Batch’s multi-node and multi-container capabilities (see figure below) lets you simulate multi-robot systems at scale, and the AWS ecosystem (CloudWatch, S3, Step Functions) provides all the building blocks for a robust CI/CD pipeline for robotics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5kdkz34e7lisxmul0gh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5kdkz34e7lisxmul0gh.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Figure: Example AWS Batch multi-robot simulation. A single AWS Batch multi-node job runs one test-scenario container and one Gazebo simulator container on the main node (Node 1), and four robot stacks (Nodes 2–5), each with separate Lidar, control, and vision containers&lt;/em&gt;&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=runner%2C%20the%20simulation%20app%2C%20and,lidar%2C%20vision%20processing%20and%20control" rel="noopener noreferrer"&gt;&lt;em&gt;[13]&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. AWS Batch’s multi-container and multi-node features enable complex simulations at scale.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt; AWS documentation and blogs on RoboMaker deprecation and AWS Batch (including AWS Robotics and HPC blogs)&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html#:~:text=End%20of%20support%20notice%3A%20On,simulations%2C%20visit%20this%20blog%20post" rel="noopener noreferrer"&gt;[3]&lt;/a&gt;&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Headless%20robotic%20simulations%20with%20AWS,what%20compute%20types%20to%20use" rel="noopener noreferrer"&gt;[14]&lt;/a&gt;&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=Recently%2C%20AWS%20Batch%20launched%20a,collaboration%2C%20and%20other%20advanced%20simulations" rel="noopener noreferrer"&gt;[12]&lt;/a&gt;&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=RoboMaker%20cloud%20extensions%20for%20ROS,in%20a%20familiar%20software%20framework" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/worlds-using-export-simulation.html#:~:text=With%20Simulation%20WorldForge%2C%20you%20can,an%20exported%20world%20in%20an" rel="noopener noreferrer"&gt;[7]&lt;/a&gt;&lt;a href="https://aws.amazon.com/batch/pricing/#:~:text=There%20is%20no%20additional%20charge,Discounts%20will" rel="noopener noreferrer"&gt;[6]&lt;/a&gt;&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=,an%20increase%20in%20this%20limit" rel="noopener noreferrer"&gt;[8]&lt;/a&gt;. These sources provided official information on service features, pricing, and migration guidance. All code examples and figures are illustrative.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=RoboMaker%20cloud%20extensions%20for%20ROS,in%20a%20familiar%20software%20framework" rel="noopener noreferrer"&gt;[1]&lt;/a&gt; &lt;a href="https://aws.amazon.com/robomaker/resources/#:~:text=Launch%20in%20GitHub" rel="noopener noreferrer"&gt;[10]&lt;/a&gt; AWS RoboMaker Resources – Amazon Web Services&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/robomaker/resources/" rel="noopener noreferrer"&gt;https://aws.amazon.com/robomaker/resources/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=AWS%20RoboMaker%20provides%20a%20fully,the%20use%20cases%20above%20is" rel="noopener noreferrer"&gt;[2]&lt;/a&gt; &lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/#:~:text=,an%20increase%20in%20this%20limit" rel="noopener noreferrer"&gt;[8]&lt;/a&gt; Introducing Batch Simulation API for AWS RoboMaker | AWS Robotics Blog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/robotics/introducing-batch-simulation-api-for-aws-robomaker/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html#:~:text=End%20of%20support%20notice%3A%20On,simulations%2C%20visit%20this%20blog%20post" rel="noopener noreferrer"&gt;[3]&lt;/a&gt; Support policy - AWS RoboMaker&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/robomaker/latest/dg/chapter-support-policy.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/iot/orchestrate-nvidia-isaac-sim-ros-2-navigation-aws-robomaker-public-container-image/#:~:text=architecture%20diagram%20depicting%20how%20the,AWS%20RoboMaker%20in%20Amazon%20CloudWatch" rel="noopener noreferrer"&gt;[4]&lt;/a&gt; Orchestrate NVIDIA Isaac Sim and ROS 2 Navigation on AWS RoboMaker with a public container image | The Internet of Things on AWS – Official Blog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/iot/orchestrate-nvidia-isaac-sim-ros-2-navigation-aws-robomaker-public-container-image/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/iot/orchestrate-nvidia-isaac-sim-ros-2-navigation-aws-robomaker-public-container-image/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Note%20that%20AWS%20Batch%20is,we%20recommend%20AWS%20RoboMaker%20simulation" rel="noopener noreferrer"&gt;[5]&lt;/a&gt; &lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Amazon%20CloudWatch%20robot%20monitoring%20sample,the%20robot%E2%80%99s%20position%20and%20speed" rel="noopener noreferrer"&gt;[9]&lt;/a&gt; &lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=Headless%20robotic%20simulations%20with%20AWS,what%20compute%20types%20to%20use" rel="noopener noreferrer"&gt;[14]&lt;/a&gt; &lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/#:~:text=2,app%60%20respectively" rel="noopener noreferrer"&gt;[15]&lt;/a&gt; Build headless robotic simulations with AWS Batch | AWS Robotics Blog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/robotics/build-headless-robotic-simulations-with-aws-batch/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/batch/pricing/#:~:text=There%20is%20no%20additional%20charge,Discounts%20will" rel="noopener noreferrer"&gt;[6]&lt;/a&gt; AWS Batch Pricing&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/batch/pricing/" rel="noopener noreferrer"&gt;https://aws.amazon.com/batch/pricing/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/worlds-using-export-simulation.html#:~:text=With%20Simulation%20WorldForge%2C%20you%20can,an%20exported%20world%20in%20an" rel="noopener noreferrer"&gt;[7]&lt;/a&gt; Using exported worlds in simulation - AWS RoboMaker&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/robomaker/latest/dg/worlds-using-export-simulation.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/robomaker/latest/dg/worlds-using-export-simulation.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/pdfs/robomaker/latest/dg/aws-robomaker-dg.pdf#:~:text=AWS%20RoboMaker%20Developer%20Guide%20End,xi" rel="noopener noreferrer"&gt;[11]&lt;/a&gt; AWS RoboMaker - Developer Guide&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/pdfs/robomaker/latest/dg/aws-robomaker-dg.pdf" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/pdfs/robomaker/latest/dg/aws-robomaker-dg.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=Recently%2C%20AWS%20Batch%20launched%20a,collaboration%2C%20and%20other%20advanced%20simulations" rel="noopener noreferrer"&gt;[12]&lt;/a&gt; &lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/#:~:text=runner%2C%20the%20simulation%20app%2C%20and,lidar%2C%20vision%20processing%20and%20control" rel="noopener noreferrer"&gt;[13]&lt;/a&gt; Run simulations using multiple containers in a single AWS Batch job | AWS HPC Blog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/hpc/run-simulations-using-multiple-containers-in-a-single-aws-batch-job/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>rpa</category>
      <category>ros2</category>
      <category>robomaker</category>
    </item>
  </channel>
</rss>
