Sep 5, 2026 · simulation · middleware · ros-2 · tooling
Which Simulator Pairs Best With Your Middleware?
Gazebo pairs best with ROS 2, MuJoCo with a stack you write yourself, and Isaac Sim only when cameras decide behaviour. Here is how to pick your pair.
Gazebo pairs best with ROS 2, MuJoCo with a stack you write yourself, and Isaac Sim only when cameras decide the robot's behaviour. The pairing that survives is the one whose connection between simulator and running programs somebody understands, which is why the plain choice usually wins. The verdict flips when photographic images are the product, in which case neither ROS 2 nor HORUS decides anything. The rest of this post is for someone who already has a middleware in mind and needs one simulator that will still fit the project next year.
You installed the simulator everyone recommended, loaded the robot model, and then spent two evenings finding out why your own program cannot see the sensor data the simulator insists it is publishing. The topic exists. The tool that lists topics shows the topic. Your program sits there with an empty callback and no error.
Meanwhile someone else has the same simulator working against a different stack in an afternoon and cannot say what they did differently, because their tutorial quietly assumed a bridge you do not have.
Then there is the other version. Everything connects, the robot drives, and the moment you switch the camera on the scene turns into a slideshow on the laptop you were told would be plenty. Somebody suggests a graphics card. Somebody else suggests a different simulator. Nobody wants to say out loud that switching means re-authoring the world, the robot description and every launch file you have written since March.
Underneath all of it sits one unspoken worry: that this pair of tools was chosen for you by a blog post two years ago, and you are now maintaining a decision nobody on the team ever made.
Which simulator should you pair with your middleware?
Pair Gazebo with ROS 2, pair MuJoCo with a stack you write yourself, and reach for Isaac Sim only when photographic images are the point of the exercise.
That reads like three answers but it is one rule said three ways. A simulator and a middleware have to meet somewhere, and that meeting point is software that somebody wrote and somebody has to maintain. Gazebo and ROS 2 meet at a bridge that thousands of people exercise every day, so when the bridge misbehaves the error message has usually been answered already by a stranger on a mailing list. MuJoCo barely meets a middleware at all: MuJoCo hands you positions and takes torques inside your own program, which is either liberating or a great deal of work depending on what you are building. Isaac Sim meets ROS 2 through a bridge that works and is nevertheless a thing you own, configure and debug.
Choose the meeting point you are willing to maintain at midnight the day before a demo. That is the real decision, and it is not the same decision as which simulator is better.
What does it actually mean to pair a simulator with middleware?
Pairing means the simulator stands in for the robot's hardware convincingly enough that your programs cannot tell the difference. That is the entire trick, and everything else is detail.
On a real robot, a driver reads a wheel encoder and publishes a number, and a planner reads that number. In simulation, the physics engine computes where the wheel would be, and something has to deliver that computed number to the planner in the same shape, on the same channel, with the same name. That something is the pairing. Do it well and you can start the same software against either the simulator or the machine, changing one line of configuration.
Do it badly and you end up with two versions of your software: the one that runs in simulation and the one that runs on the robot. That is the failure people call sim-to-real trouble when the real problem is that two stacks drifted apart, and nobody noticed until the robot did something the simulation never had the chance to do. Understanding why a robot that works in simulation fails in your kitchen starts here, at the seam.
What are the real options on each side?
There are roughly four simulators worth a small team's attention and three middleware answers, and the useful combinations come from that short list.
On the simulator side: Gazebo, the general-purpose whole-robot simulator; Isaac Sim, the photographic one built on NVIDIA technology; MuJoCo, the contact specialist that researchers reach for; and Webots, the friendly one that installs without a fight. PyBullet still turns up in older reinforcement learning work and in teaching material.
On the middleware side, the honest list is shorter. ROS 2 is the default and carries the largest ecosystem of drivers, tools and tutorials in robotics. HORUS is an open-source real-time middleware for Rust, Python and C++ in which those three languages share the same shared-memory ring buffers, so messages between programs on one machine are not serialised; the licence is Apache-2.0, the project is validated in simulation, and pairing that middleware with a simulator means writing the connecting piece rather than inheriting one. The third answer is no middleware at all, which is what a single Python program driving MuJoCo really is, and which is a perfectly respectable answer for a research question.
Which pairings do teams actually run?
These are the combinations that show up repeatedly in real projects, along with the situation each one suits.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| Gazebo with ROS 2 | Teams building a whole robot with sensors | Basic ROS 2 concepts and launch files | Testing whether your programs work together | When photographic images decide behaviour |
| Isaac Sim with ROS 2 | Vision-driven products with NVIDIA hardware | ROS 2 plus scene authoring and GPU drivers | Training or testing a model that reads pictures | When half the team lacks an NVIDIA card |
| MuJoCo in one program | Researchers studying contact and control | Python and the maths of your own controller | Studying a grasp, a gait or a control law | When you need drivers, maps and sensors |
| Simulator with HORUS | Builders wanting one machine, several languages | Writing the connection between simulator and code | Mixing Rust, Python and C++ on one computer | When you want a ready-made bridge to inherit |
| Webots with ROS 2 | Absolute beginners and classroom use | Almost nothing beyond installing software | Getting something moving in an afternoon | When the project outgrows the sample worlds |
| Isaac Lab on Isaac Sim | Policy training at volume | Reinforcement learning and NVIDIA tooling | Learning a walking or grasping policy | When you have not yet trained anything |
| PyBullet in one program | Tutorial followers and older codebases | Python and patience with ageing docs | Reproducing published work that used PyBullet | When starting something new today |
Read the last column first. Most bad pairings are not wrong choices; they are right choices kept past their moment.
Which pairing fits a solo builder, a small team, or a lab?
A solo builder should pick Webots or Gazebo, a small product team should pick Gazebo, and a research lab should pick whatever the paper they are chasing used.
The reason is not taste. A solo builder has no one to hand a broken bridge to at eleven at night, so setup cost is the dominant term and everything else is theory. Webots gets a robot moving in an evening and Gazebo gets a robot moving in a weekend, which is the difference between finishing and drifting.
A small product team has a different constraint: everyone must be able to run the thing. A simulator that only the person with the good graphics card can start is a simulator that quietly becomes one person's private tool, and the tests that depend on it stop being run.
A lab has the opposite constraint. Reproducing or extending published work means matching the environment the work used, and arguing about simulator quality is beside the point when the comparison has to be like for like. If you are choosing more broadly, the three main simulators divide the work along clear lines.
What hardware do you have, and what does that rule out?
Your hardware settles this before your preferences do, and it settles it in one direction: photographic rendering demands a recent NVIDIA card and everything else does not.
If the team's machines are laptops with integrated graphics, Isaac Sim is not a slow choice, Isaac Sim is not a choice at all, and no amount of enthusiasm changes that. Gazebo, Webots, MuJoCo and PyBullet all run on ordinary computers, will happily use a modest graphics card if one is present, and degrade gracefully by dropping visual quality rather than refusing to start.
The second hardware question people forget is the target, not the desk. If the robot's brain is a small board tucked inside the chassis, the simulation is running on a machine unlike the one the software will live on, and the parts of the system that are sensitive to timing will behave differently there. That gap is not a simulator problem and no simulator fixes it.
The third is disk. Photographic simulators arrive at the scale of an operating system, with assets to match, and a team on shared laptops feels that within a week.
How soon do you need this working?
If you need a simulation running this week, pick Webots or Gazebo, because both are chosen and forgotten in days rather than negotiated over a month.
Timeline is the axis people underweight most badly. The cost of a photographic simulator is rarely the download. The cost is authoring: a warehouse that looks convincing is a modelled warehouse, with materials, lighting and clutter that someone placed. That is real work by a skilled person, and on a small team that person is usually the one writing the control software.
If your deadline is a demo in six weeks, the question is not which simulator produces the better picture but which one lets you spend five of those weeks on the robot's behaviour instead of the scene. If your deadline is a year out and the product is a vision model, the arithmetic reverses, because the scene is the product and the behaviour follows from the model.
Ask what the simulator must prove before your next deadline, then pick the cheapest tool that proves it. If the machine you are targeting is one nobody on the team owns yet, that shifts what simulation can settle and what it cannot.
What does each pairing assume you already know?
Every pairing assumes a body of knowledge you either have or will acquire under deadline pressure, and the honest comparison is between those bodies rather than between features.
Gazebo with ROS 2 assumes you can read a launch file, describe a robot in the standard XML format, and reason about a bridge that translates between two message systems. That is a real week of learning, and it is a week thousands of people have documented.
Isaac Sim with ROS 2 assumes all of the above plus scene authoring, GPU driver management, and comfort with a tool whose documentation moves faster than the tutorials chasing it.
MuJoCo assumes something quite different: that you can write the loop yourself. There is no launch system to learn because there is nothing to launch. You call a step function and read the state. Whether that is simpler depends entirely on whether you wanted a framework in the first place.
A simulator paired with a middleware you write against directly assumes you can build and own the connecting piece. That is a smaller job than people expect and a job nobody else will do for you.
What does a bad pairing look like six months in?
A bad pairing announces itself as a simulation nobody runs any more, and the announcement is always indirect.
The pattern goes like this. Early on, everyone runs the simulator before pushing changes. Then the bridge breaks after an upgrade and one person fixes it locally without writing anything down. Then the scene starts taking too long to load, so people test on the real robot instead because the real robot is right there. Then a new joiner cannot get the simulation running at all and nobody has an hour to help. Six months later, the world file references a mesh that was moved, and the last person who understood the launch sequence has changed teams.
The tell is not a complaint about the simulator. The tell is that bugs are being found on hardware. When the physical robot is your first line of testing, every bug costs a booking, a battery and a person, and the pace of the project drops without anyone deciding it should. This is also how teams end up continuing to simulate long past the point they should have built the real thing, or the reverse.
What do you give up when you commit to a pairing?
You give up portability, and you give it up quietly, in small pieces, over months rather than all at once.
Choosing Gazebo with ROS 2 means your world files, robot description, sensor configuration and launch files encode assumptions from both tools. Moving later is not impossible; it is a fortnight of unglamorous work that never appears on a roadmap, which is why it does not happen.
Choosing Isaac Sim means committing the team to NVIDIA hardware for anyone who needs to run the simulation, which is a purchasing decision disguised as a software decision, and one that outlives the project.
Choosing MuJoCo inside your own program means giving up the ecosystem. No off-the-shelf navigation, no visualisation tool everyone already knows, no driver for the depth camera you buy next year. You get exactly what you write.
Choosing to write your own connection between simulator and middleware means owning that piece forever, including the day the simulator changes an interface. The compensation is that when the connection breaks, you are the person who understands it.
When is ROS 2 the better choice?
ROS 2 is the better choice whenever the ecosystem is doing more work for you than your own code is, and for simulation that is most of the time.
Concretely: you want a navigation stack that already exists, you want to visualise sensor data in a tool your whole team knows, you want a driver for a lidar that ships with a maintainer, or you want to hire someone next quarter who can be useful in their first week. Simulator bridges are the sharpest case of all, because Gazebo, Isaac Sim and Webots all ship connections to ROS 2 that somebody else maintains, and none of them ship a connection to anything else. Choosing ROS 2 here means the bridge is a download rather than a project.
HORUS is not the answer for that team. If your project is mainly assembling existing robotics components and the timing between your own programs has never once been the thing that broke, adopting a different middleware buys you a problem you do not have, and costs you the tutorials, the packages and the strangers who have already fixed your bug. Take ROS 2 and get on with the robot.
Will switching middleware fix a slow simulation?
No, and here is why: the simulator and your software are two separate workloads, and the one making your machine struggle is almost always the physics and the rendering rather than the messages between programs.
A scene with detailed contact, many articulated bodies and a camera producing images is doing an enormous amount of arithmetic every step, and it does that arithmetic whether your programs are chatty or silent. Changing how those programs talk to each other does not reduce that work by a single triangle. People reach for the messaging layer because messaging is the part they can change, not because messaging is the part that is loaded.
The genuine exception is when your own programs and the simulator are competing for the same machine. Then a stack that copies large images repeatedly between processes is taking capacity that the physics engine wanted, and the fix is architectural rather than cosmetic. But you diagnose that by turning your own programs off and watching whether the simulator recovers, not by rewriting the stack first and hoping. Measure which half is struggling before you change either one.
Is the simulator to blame when the real robot behaves differently?
Partly, but not the way you think. The simulator is usually wrong about friction, contact and the flex in a gearbox, and those errors are real, but they are rarely the thing that makes a working simulation into a hesitating machine.
The gaps that ruin a demo are usually about time. In simulation, the physics waits for your program. On the robot, the world does not wait, sensor data arrives when it arrives, and programs compete for the same processor. A planner that was always given a fresh view now sometimes acts on a stale one, and the machine develops a stutter that no amount of friction tuning removes.
You can tell the two apart without buying anything. A physics gap repeats: the robot always understeers on that carpet, always misses that shelf by the same margin. A timing gap does not repeat, and it worsens when everything is running at once. Run the robot with the heavy programs disabled, and if the behaviour cleans up, the sim-to-real story you have been told is the wrong diagnosis.
How should you decide this week?
Write down the one thing the simulator must prove before your next deadline, then choose the pairing that proves it with the least authoring work, and revisit the choice only when a new question arrives.
- If you are testing whether your programs work together -> Gazebo with ROS 2, because the bridge is already worn in by thousands of people.
- If a trained model reading images is the product -> Isaac Sim, because the pictures must convince a network rather than a person.
- If you are studying one grasp, gait or control law -> MuJoCo in a single program, because contact is the whole question.
- If nobody has simulated anything before -> Webots for a week, because momentum matters more than correctness at the start.
- If your team mixes Rust, Python and C++ on one computer -> pair your simulator with a middleware built for that, and accept that you write the connection.
- If the simulation is fine and the hardware stutters -> stop buying fidelity, because the fault is timing rather than physics.
The HORUS Fit Framework keeps this to five things you can judge without running anything: ecosystem size, setup effort, team size fit, deployment target and licence. For pairings, setup effort and deployment target decide it most often.
The week your simulated robot behaves and the real one hesitates is a poor week to start reading about the layer underneath. Put HORUS on the shelf before then: star it so it is in your list when you start building.