Help wanted in implementing Rocker-Bogie suspension system for a rover

Hello all, this is my first forum post and I guess it doesn’t hurt to ask for help here.

I’m an engineering student working on a simulation-based project using Unity and MATLAB. I have to implement several autonomous vehicles in Unity and connect with MATLAB/Simulink to perform control and generation of setpoints, etc. So far, I’ve had success in implementing a quadcopter and an underwater vehicle and the LQR/PID controllers work really well in Unity. However, I haven’t got it to connect to MATLAB so far, the controllers were implemented in Unity itself but that’s an issue for another day.

I have 3 remaining systems left, a rover, a quadrupled robot, and a self-landing rocket. I’m currently working on the rover which is supposed to operate similarly to how the real Perseverance rover does. See the RB.PNG attachment which shows the closest I could get to some satisfactory result. Besides the body, which is the parent rigid body, the left and right rockers, bogies, 4 steering controllers, and the 6 wheels are child rigid bodies and are connected together with configurable joints.

I did not use WheelColliders for the wheels, they are just rigid bodies which surprisingly moves the whole rover by applying torque to the wheels. No issues encountered here but when I start changing the front and back wheel angles for steering, the whole system just becomes unstable and does not turn as expected.

I think it has to do with the center of mass of the parent and the colliders (See Colliders.PNG), which I had to modify for the rocker-bogie to “work” to some extent. Another issue is that this system basically does not work at physics time steps smaller than the default (0.02), but I need to standardize of all of systems to work at 0.01 since the controllers for the drone and UAV only start working with that setting.

I know I probably need to send more info, but I don’t want to make this starting post any longer than it needs to be. Any suggestions?


Nice project! And welcome to Unity forums :slight_smile:

At first sight, the cause is probably the difference of masses between the parts that are connected, especially if low mass rigidbodies (wheels and rods) are supporting high mass rigidbodies (rover’s body). This typically doesn’t get well with joints, requiring either the physics running at higher rates, or artificially scaling the inertia of the lighter elements. Definitely, just running at 100 Hz (timestep = 0.01) shouldn’t make the system worse. If all, it should be more stable.

First I’d try to confirm if this is the cause of the issues. Set all masses to be in the same order of magnitude, like 500 for the body and 300 for each rod and wheel. If now it’s stable, then you may either:

  • leave it that way (anyways the sum of the weights should be the same)
  • go back to the realistic values and then scale the inertia (multiply rigidbody.inertiaTensor with some number from a script). Scaling the inertia provides a “stabilization” effect while preserving the weight.

If the problem persists, then there’s some other issue. You mention that turning front and back wheel angles for steering makes the system unstable. Maybe the wheels are now colliding with some other collider? From your picture, I see that the rod connecting middle and rear wheels is pretty close to the collider of the wheel:

8587096--1150891--upload_2022-11-15_10-50-45.png

First, ensure that the “Enable Collision” check in the joints is disabled. Also, check that the colliders of the wheels are not colliding with another collider of the vehicle. Even with all “Enable Collision” flags disabled, wheels may collide with the other vehicle colliders they’re not attached to.

Hope this helps! Please post your results when you get it sorted.

Thank you for replying, Edy.

Originally when I said a lower physics timestep makes it worse, I meant the rocker-bogie would not behave as how it should as the wheels are supposed to stay grounded as long as the elevation difference between the sides are reasonable enough (See physics for the different timesteps attached). However, thanks to your suggestion, I changed to mass as follows: Main: 500kg, Rockers and Bogies: 50kg, Wheels and Steering (joint which connects to the steerable wheels providing an angular Y constraint): 300kg. I needed the wheels to be heavier for them to stay grounded and it works (See Physics at 0.01 with Modified Masses). So, you were correct about the mass issue, as I had originally kept all the masses equal as NASA only provided the overall mass of the rover and not the individual masses of the components.

So, the next issue arises, and this was always before the steering issue which I will address after this one. For now, I want to fix all the issues when the steering angles are zero (I will edit the colliders by then). One issue is that when the rover moves in a straight line with equal torque applied to all wheels and no obstructions, it yaws (rotation about Y). The yaw is fairly slow, but I believe it gets slower the higher the applied torque but as you know, rovers aren’t supposed to be fast. I think it has to do with how the net speeds on the left and right sides are unequal resulting in a torque. The code for the wheels in FixedUpdate() is fairly simple:

wheelRigidbody.AddTorque(transform.right * (torque * gearRatio));

where torque and gearRatio are serialized.

When the torque to all wheels is zero, the rover looks like it stays in place but there is still a yaw occurring and some of the wheels are rotating slowly. When the torque on the left and right wheels are equal but opposite in sign, the rover does not yaw much in place but instead moves either reverses or moves forward depending on which side has the positively applied torque. Previously with the outdated setup, giving the wheels a non-zero inertia in the Y and Z axes would fix this but now it just moves in one direction as I said with 0.01 as the physics timestep. Any suggestions?


8587993--1151107--Physics at 0.01.PNG

I haven’t got much to contribute, but I recommend to have a look at “ArticulationBody”. It’s another solver in physx for tree-like joint structures. I have a hunch that the whole rover system is somewhat (numerically) unstable and vibrates which by chance induces some yaw.

Tried that and got better stability. Problem is that now it won’t move at all when torque is applied to all wheels and the rocker-bogie does not behave like one when moving it in the editor when the game is running. Moving it just causes it to reset as if it cannot move at all despite the immovable option being unchecked.

The main body is the root, the rocker and bogies are revolute joints with a [-60, 60] X constraint, but the steering motors and wheels are rigid bodies as configurable joints since the steering motors require a [-45, 45] Y constraint. Not sure what I’m doing wrong.

EDIT: I realized there’s the spherical joint which has revolute axis constraints so now the whole thing is an articulation body. I am getting no yaw and it actually moves when torque is applied to the wheels. One issue is that the steering motors rotate on their own, but I only want it to be controlled by script. I tried a fixed joint but there might be problems later on. The rocker-bogie is not acting the way it should with the articulation body as I said before still. See Physics with Articulation Body.PNG. It still moves straight with the wheel angles changed so I am very confused.

EDIT: I might need some help with the articulation body setup for the rocker-bogie itself. It could be that it’s supposed to behave that way with the current setup I have. Usually, if one side is lifted, the other side will assume the opposite rotation so I’m guessing why my setup is wrong is because I did not use the bar differential which is supposed to perform that function (See Bar Differential.PNG). I’ll try something with just the rocker-bogie with the body disabled and post again if anything. It might end up just being me coding the whole thing rather than hoping for a simple solution without code.

8590651--1151731--Physics with Articulation Body.PNG
8590651--1151854--Bar Differential.PNG

Assuming that ground is level and no obstructions (as you stated) have you checked the physics materials you’re using for the ground and the wheels? Are the wheels using same material, etc.

Also looks like you’re using capsule colliders for all your wheels. I would double check that they are all exactly the same size since if they are not then amount of friction between the wheel and the ground will be different and you would get anomalies. In my opinion.

I didn’t use any physics materials yet. I changed to sphere colliders since I’ve seen in forums that sphere colliders are used for wheels in articulation bodies. Will check if there are the same size though.

EDIT: I need to break the problem down into small pieces. So first, the wheels. They go forward when torque is applied equally to all wheels, so that works. Now, when I apply equal torques on both sides but opposite in sign, it does not result in rotation and instead stops in place. Furthermore, changing wheel angles in the front and back also does not cause any rotation. When I used rigidbodies, the problem was fixed by just having a nonzero inertia in the Y and Z axes (initially I had it zero because locking rotation in the rigidbody settings does that). When I change the inertia in the articulation body for the wheel though, it just flies in the air. I’m can’t seem to reason why, though.

EDIT (Again!): Turns out it DOES steer as long as all wheels have the same torque. However, real rovers actually rotate the wheels on the side you want to steer in the reverse rotation. This effect does work with WheelCollider so I’m not sure why I can’t get the same effect with the wheels treated as a revolute joint.

P.S. Please don’t recommend WheelCollider, I need gears and from my experience, controllers do not work well with it.

Minor bit of info - the articulation body solver is dependent upon the inertia matrix of the bodies, I recommend you set them manually by script (or they will be calculated from the collider volumes): I seem to recall using (1, 1, 1) to make them work a couple of years ago (and I did not find them very robust), perhaps things have moved on since then, so you probably need to experiment.

It’s old and I have not looked at the source, but it may be worth checking this for ideas:

Fixed the steering problem. Turns out it was the sphere colliders being unequal size resulting in uneven lateral resistance when trying to rotate the body. This works if the angles of the steering wheels are set before running the game. If I try to change the angles during simulation with a script, it does not work, so I guess it’s because I assigned Euler Angles treating the object as a transform instead of an ArticulationBody. Going to try and find the appropriate method before I post more issues. It HAS gotten better using an ArticulationBody for sure, I am very close to getting something satisfactory enough for my uses.

I saw that video you attached when I started the rover weeks ago, but his rocker-bogie has pretty much no physics attached to it. His method of keeping the wheels on the ground is inaccurate for my uses. When one rocker has to rotate to go over an obstacle, the other rocker is supposed to rotate in the opposite direction which keeps the wheel on the ground (See Correct RB Behavior.PNG). Mine does that due to the weight of the vehicle just like his (See My Rover Bogie.PNG), but I think it could be solved by just making the bar differential a revolute joint (See Perseverance Bar Differential). I need to modify the mesh in Blender first though, as NASA’s official model didn’t even have the wheels as separate entities, so I had to split them manually!

8593489--1152349--Perseverance Bar Differential.PNG
8593489--1152352--My Rover Bogie.PNG
8593489--1152355--Correct RB Behavior.PNG

Now steering works in realtime in simulation by using jointPosition. A new problem though, the rover still yaws with no torque applied and if I change the wheel angles, the wheels rotate on their own. I tried changing joint friction and stiffness values of the wheels and while that stops the wheels from spinning, it becomes harder to apply torque and also the rover still spins anyways. Is it a center of mass issue? I will try manipulating inertia values but from my experience with articulation bodies, it just flies into space when I try that.

I updated the colliders for the Rocker-Bogie (See New Colliders.PNG). I disabled the body for now, since I want to address the steering problems first and the body has its own colliders affecting the center of mass.

8593924--1152418--New Colliders.PNG

Seems to me like you’re dealing with multiple issues at once. I would try to isolate each of the pieces and confirm that they behave as I would expect them to. That given input they effect expected output. For instance, if I understand correctly the wheel issue, I would take one of the wheels with a joint that you’re using to rotate the wheel and just test that in isolation to see if it spins or not when turned. If it doesn’t then you confirm that that portion of the system behaves as you expect (and the problem is something else), if it does rotate then you’re dealing with a much smaller possibility space as to what could be causing it and could isolate it faster/easier.

But even so, when I change the angles before simulation it will steer correctly, but when I change them during simulation in a script, the wheels rotate on their own when no torque is applied. It becomes very difficult to stop the wheels once torque is applied and then set to 0, so it could just be that I need physics materials because angular damping and revolute joint damping does nothing. Braking torque seems like a good solution but I reckon a speed controller would do the job better. Thanks for your suggestion though, will do later.

Hmm, the only thing I can think of is, are you sure that the wheels are experiencing friction with ground while they are being rotated. Is the axel on the wheels perfectly centred at the centre of the wheel. If you turn the wheel without it touching the ground, do you still get wheel movement. If so what is the nature of the wheel movement, is it in one direction vs. another. Can you verify that that happens on all the wheels individually, if it does then issue is more systemic setup issue, if they behave differently (not all the same way) then maybe it is a minor misconfiguration on particular wheel.

It has to do with the center of mass. I get different results depending on where I place the articulation bodies. It seems a combination of articulation bodies and rigid bodies is the way. I’m getting the effect I want where the joints are pushing the links attached to the bar differential (See RB Joint and Link.PNG), will play around more with configurable joints. I will post some results when I figure it out but what I’m trying is an articulation body for the rocker-bogie and a rigid body to allow multiple configurable joints to connect the bar differential and the rocker-bogie together since I might need a two parent-child relationship.

EDIT: For some reason, the link between the bar differential and rocker joint is moving on its own when the rover is running. Each link has 2 configurable joints connected to articulation bodies, one connected to the differential bar and another to the rocker joint. Not sure what is going on (See Configurable Joint Bug.PNG).

EDIT: It will be a while before I return to this (at least a week or so). For now, I will be working on other parts of the project I could make progress on, such as connecting Unity and Simulink together.

8597464--1153138--RB Joint and Link.PNG
8597464--1153177--Configurable Joint Bug.PNG

For some reason, the articulation body is “rotating” (from 0 to 34.886) causing the body to tilt to the ground, despite the rocker mesh not appearing to be physically rotated at all. I think I am just going to code it based on models I found in research papers because I am unable to make sense of anything from my most recent attempts at this.

EDIT: Never mind, it’s a weird oversight but apparently, I had to set the limits of the X drive to be -90 to 0 instead of -45 to 45. Now the mesh physically tilts without the body rotating.

As for the steering problem during simulation, it might be due to an instant pose change to the articulation bodies. Will try something equivalent to Slerp and see how that goes.

What I realized from the rocker though, is that the transforms and the articulation bodies attached to it are not necessarily related. Changing euler angles before simulation will alter the behavior of the articulation body if you do not change pose but not during simulation (where it has no effect on the articulation body, but the mesh does physically rotate). Changing pose on the other hand behaves odd, so it might be my transform rotation is not matching the pose for the same weird reason I had with the rocker.

EDIT (2): Fixed the steering problem, turns out I was right. Also, I figured out the random yaw in standstill is due to the wheels having some torque by observing their angular velocities. I have the controllers for that, so I guess that’s a simple fix.

Remaining problem is implementing gears. I usually multiply the torque by the gear ratio and change the inertia by the square of the gear ratio so the angular velocity should adjust accordingly. That used to work for rigid bodies, but the articulation body version causes the rover to fly off into space when I modify the inertia so I’m not sure what’s going on.

Skimmed through the thread and I saw that a few messages above you mentioned using a spherical joint. Launching the whole Articulation Body tree into space is sadly a characteristic of spherical joints in PhysX, we usually recommend using multiple revolute joints for each axis of rotation instead.

P.S. Looks like a lovely project! And I think choosing Articulation Bodies for this is the correct choice.
Random tip: when using Articulation Bodies, the TGS (Temporal Gauss Seidel) solver seems to produce better (and more stable) results. You can switch the solver in the Project Settings.

Thank you for your response! Yeah, I forgot to mention I did switch to revolute joint with the correct axis of rotation for the corresponding articulation bodies and it functions the same. TGS gave me varying results when I previously used rigid bodies, so I will check again with this version.

I think I implemented the gears wrong? In Simulink, I would multiply the torque and divide the angular velocity outputs by the gear ratio, but in Unity, overwriting the angular velocity would be erroneous since the applied torque information would be erased. I noticed the wheels would not go over bumps unless the angular velocity was large enough rather the torque so I figured I must be implementing something wrong.

EDIT: If I multiply the x component of the inertia tensor by the square of the gear ratio which I assign anything other than 1, it just crashes Unity. I tried rigid body again and it works but when I attach it to the articulation body with configurable joints, the tires do spin but no rover movement occurs. I can’t make the whole thing a rigid body again because that will just bring me back to square one. I guess I need to give up on gears for now until Articulation Bodies could handle large inertias and torques. For now, I’ll accept that I have a working rocker-bogie but a fast-moving rover :smile:.

If there really is no other way, I guess this thread has achieved its purpose for the time being. This thread was about the rocker-bogie, so the gears are a separate topic. Thanks everyone for the help. Articulation Bodies did the trick :).