RoveSoSimulator

Autonomous Rover Testing Simulator in Unreal Engine 5

View the Project on GitHub MissouriMRDT/RoveSoSimulator

Return to RoveSoDocs Guides for Today, Tomorrow, and Forever.

Initial Arm Development and Implementation Process

Under Development

arm diagram arm diagram with rotations

Overview

This Page discusses the setup for the arm, with a focus on how it works but not so much how to remake it, as future iterations will build off whats there, and this is the first arm.

  1. Skeletal Mesh

    The model of the arm; what you see.

  2. Skeleton

    Base setup for moving/manipulating the mesh (#1)

  3. Control Rig and Animation Blueprint

    Set up for manipulating the bones (#2) which manipulate the mesh. Necessary piece inbetween skeleton and actual control values

  4. Blueprint

    Container that connects the previous assets together with other things, such as the keyboard inputs and the lasers.

  5. Physics Asset

    Hitboxes and such.

  6. On the Rover and Taking Control

    How switching to the arm from the Rover works

  7. Tutorials and Sources and Such

    Links to tutorials used.

  8. Futher notes

    Additions made/to be made after implementation, such as switching to the enhanced input system and better physics.

Skeletal Mesh

Placed in the Blueprint; not really “assigned.” However, other components, including the skeleton, control rig, and animation blueprint, have it assigned as a preview mesh. Contains assignments for skeleton, control rig, and animation blueprint. The skeleton appears to be assigned under mesh, but cannot be switched out (???). The control rig is assigned as the default animation rig, and the physics asset is assigned under physics. Noteability, the Control rig assignment may not do anything. However, the Physics Asset assignment is done here in the Skeletal mesh rather than in the blueprint; no other known options.

Pre-Unreal

Due to the sheer size (# of pieces and vertices) of the arm CAD file, it was decided that it would be easier to make the arm manually with measurements—with the exception of the gripper—rather than process the CAD file directly.

Unreal

The mesh was imported as a static mesh to make reimporting easier, as you can just press reimport on the mesh, the a skeletal mesh can have strange material conflicts. The static mesh can be converted to a skeletal mesh by right clicking on it in the content browser. There you can also choose whether to make a new skeleton or using an existing one—the latter of which is what to do when reimporting to fix the mesh.

Skeleton

Auto (???) assigned in the Skeletal Mesh. Does not appear to assign anything functional itself, but does have a Preview Mesh that should be assigned to the applicable Skeletal Mesh. Edited in the skeleton mesh for some reason.

One bone per joint/axis; J1/x-axis though J6. Gripper has an ten bone structure; 5 for the left, 5 for the right; 4 are in a chain, and the last of them does not affect the mesh, but instead acts as a reference for the one bone not in the chain. The multitool’s Solenoid is a single bone. After the skeleton is complete, you can weight paint in another section of the skeletal mesh. Note: I have experienced consistant crashes related to weight painting where unreal completely crashes when you hit “accept”. Make sure the skeleton is saved before weight painting. If it crashes when you hit accept, the issue will likely be with the geometry of the mesh, though I’m not sure exactly how, as my experiences differ slightly;

  1. The bicep distinctly and seemingly some pieces of the gripper had strange geometry. Solution; redo that geometry
  2. Later, the camera pieces, which were redone a few times, had an issue where either a certain area or a certain amount of geometry would cause them to crash. In other words, the vertices could not be deleted and remade. Solution; add a ridiculously high vertice count sphere, try some importing, and then delete the sphere and reimport (not precise, really a chuck it at the wall solution).

Control Rig and Animation Blueprint

The Control Rig is assigned to the mesh by the blueprint, animation blueprint, and (possibly nonfunctionally) by the skeletal mesh. Assigns itself a preview mesh; does not appear to connect any other assets.

The Animation Blueprint has not been experimented much with, but it has a node aptly called the “Control Rig” that seems to connect the control rig to the Animation Blueprint (which is later connected to the mesh in the Blueprint). It also has a preview mesh.

The control rig contains controls; one for each joint J1-J6, one for the solenoid, and one for each side of the gripper. The each of the gripper’s controls modifies the rotation of two bones; one to move the sides entirely, and another to keep the jaws straight. Additionally, the reference bone is used to point another bone toward it. The Forwards solve updates the bones bases on the controls as the game runs (every frame or something). The Construction script runs when the object is constructed; this means it actually runs in the Blueprint as well—this can be seen by selecting the control rig in the blueprint. The Construction script sets up the arm’s default position (changing it can make testing far more convenient, but make sure to set it back). The Custom Function QuartClampViaEuler is used for applicable bones to limit the bone’s rotation (not translation though). It is functionally a failsafe, preventing bones from moving out even if the controls are somehow moved out of place; this makes the control rig limits functional in the control rig viewport. If the blueprint limits were removed, you would be able to rotate the controls beyond what the bones actually do, and have to move the extra distance back before being able to see control affect the joints again.

Blueprint

Contains a number of components, including ones for the control rig and the skeletal mesh. The Skeletal Mesh Component assigns the skeletal mesh (under “Mesh”), as one would expect, and the Animation Blueprint (under “Animation”). The Control Rig Component only connects with the Control Rig Class.

A node called “Add Mapped Skeletal Mesh” occurs on the Event BeginPlay and I believe connects the Skeletal Mesh to the Control Rig; however, it may be reduntant with the Animation Blueprint’s Control Rig assignment

Nodes

The Blueprint modifies the location of each control in the control rig, which then modifies the bone. This is done with a custom function named “boneControl,” which condenses all of the functionality. Bone control only modifies one bone at a time, and only either the position or the rotation. Limits are in degrees or centimeters, and are set as vectors for condensation. The rate is in degrees per second or centimeters. The limit checkmark determines if it applies a limit (uncheck for infinite rotation). It is possible to move or rotate a single bone along multiple axiis, and even at different rates, but a single bone Control node can not be used to move multiple bones (besides how children are moved by parents) nor to move a single bone by input axis values from different input axiis. If bone control is not working, make sure rate, min and max are all set to the same axis. Don’t forget to check the control rig, which also has its own limits to apply.

The Blueprint activates and deactives lasers by changing visibility. It also connects a Skeletal Mesh and a Control Rig from Event BeginPlay (possibly redundant). Finally, it has a number change system to cycle through Cameras.

Components

The Skeletal Mesh Component contains the visible arm, along with its bone references; as such, components such as the lasers and the Cameras are its children, allowing them to connect to the bones under the “Sockets” section. The Control Rig Component contains the KeyboardTestingPoint, an empty body used to place keys such that they can easily be pressed when the arm is spawned in. The Control Rig has some visibility issues in the viewport; turning the camera about and possibly selecting the control rig make it easier to see. The Outer View Camera is an arm position reference; very useful to know what position the arm is in without having to navigate with freecam. Noteably, freecam functions strangely when started from a rotated perspective; going from the third person camera fixes this.

Physics Asset

Assigned by Skeletal Mesh. Has a Preview Skeletal Mesh asset that can be reassigned; does not appear to assign anything else.

The Physics Asset contains the Collision Hitboxes for the mesh/skeleton. All (should be) kinematic, meaning they push but don’t get pushed; this isn’t quite the desired ability, as the arm can phase through the floor and can “crush” an object (just causes object to move around weird until it is free again). Boxes are primarily used for collisons; the exception is a nonuniform octoganular prism on the solenoid. Some joints (bend points, not arm segments) do not have collisions, though I now believe the physics bodies can be set to not interact with each other. Finally, only the “inner” parts of the gripper have a hitbox; these points are essential for accurate gripping, though the rest should be given something to make collision more accurate.

The Physics Asset also contains constraints; however, they are inconsistant about matching their bone’s limits. This may not matter because they are currently kinematic.

The Physics bodies being kinematic may also mean they are driven by the bones rather than driving the bones, as I believe when set to “Simulated” the bones will not move. Unfortunately, the desired interaction is a hybrid, where it move if it can. Future Problem.

On the Rover and Taking Control

Occurs in the Client Controller Blueprint, in the RoveSoSimulator folder. A reference here will need to change to make possession possible for new arms, and will have to switch each time the rover is switched :(.

Switching from control of the Rover to the arm requires possessing a component of the Rover. Unfortuately, the arm’s status as a component of the rover makes this difficult, since unreal doesn’t like to interpret it as a pawn. Solution; on begin play, all actors of the arm class are found, and the first one in that list is made a reference for the Client Controller. There are two problems with this;

  1. No idea how this will function with enhanced input.
  2. Having multiple players (currently outdated) or having an arm already in the scene will break it, as everyone will have the same reference/the reference will be for an arm not on the rover
  3. Making a new arm blueprint will break it.

If you are looking for the button to switch control between the rover and the arm, it is “U”, and due to how Client Controller Functions, this button is the same for both rover to arm and arm to rover.

Tutorials and Sources and Such

Lasers (5 stars, 2 tutorials in one, only need the first part) - [https://www.youtube.com/watch?v=DIaUFv_ogNs]

Further Notes

Future Additions/Lacking Implementations




OLD STUFF

Overview

++++++++++++++++++++++++++++++++++++++++++++++++++

Pre-Unreal: Measurements, Mesh, and the CAD Gripper

Due to the sheer size (# of pieces and vertices) of the arm CAD file, it was decided that it would be easier to make the arm manually with measurements—with the exception of the gripper—rather than process the CAD file directly. The given measurements are as follows; x-axis - 21 inches long, 6 inches tall, Depth Carraige - 1 inch of thickness, height and length made to match shoulder connection Shoulder - 5.5 deep from x-axis out, 4.5 side to side, bottom of shoulder level with bottom of x-axis,

Gripper - unknown/forgot to write down/get. Used an image to approximate

**Bold values are lost/unclear/weren’t measured, italized are creator’s choice due to negligiblily (also not measured).

The Gripper was exported without bolts/screws/whatever-I’m-not-mechanical, as an .obj file with measurements set to inches (maybe unnecessary, see next section). A toggle I forget the name of seemed like it would be good to press, but actually caused a bunch of things to have scrambled rotation. Double check that the file you get (if you get one) has correct position and orientation. Scale may not matter (or work), but you will want them rotated correctly and positioned so one side is a mirror of the other (rather than one being full up and the other full down or whatever)

Creating the mesh

The Mesh was created in Blender. May want to see some tips on how to use it. The mesh was set up so the lower-left?-rear point of the x-axis is at the origin.

To make your measurements

  1. set up units to be inches (or whatever you are using) by going to Properties (a window type) -> Scene -> Units.
  2. go into edit mode (top left, or click tab sometimes) after selecting the mesh (create one if necessary)
  3. select a vertex, press “e” to extrude (create a new vertex connected to the old one), press “x”/”y”/”z” (locks the movement of the vertex to one axis) and type a number (extrude that number of inches in chosen direction)
  4. Repeat to create the distances in the file. You can use the measure tool (too long to explain here) to double check your work.

The Pivots

  1. The x-axis doesn’t need much, but don’t forget the carriage exists. I made it shaped like an “I” / sidesways “H”, but I geniunely forgot what it looks like.
  2. At J2 and J3, creating a cyclinder and a tube bigger than the cylinder at each of the points works well.
    • use ctrl-r and face extruding to get the tubes connected. You may want to cut your tube to have extra disks at both ends to connect the cylinder on one side.
  3. At J4 and J5, inseting (extrude down along normal z) a circle base to create a hole for a cylinder works well. Adding the cylinder for the other piece.

The Gripper quick tip! hover over something with your mouse and press “l” to select everything linked to it. This changes slightly if you are in vertex v. face selection mode

  1. Before you join it with everything else, you should probably scale it correctly; importing with .obj (in my experience) doesn’t preserve units. It will likely be placed in meters, so look up the conversion and (in edit mode) scale down the whole thing by the right value.
  2. Also before you combine it, you can…
    • press “p” in edit mode to separate things, including by loose parts. If you go to “3D Viewport” (window type) -> “Show Overlays” arrow (top right) -> “Statistics” checkbox, you can see how many vertices each thing has. You may want to get rid of the less significant but large vertex count pieces, such as the gears. Otherwise…
    • Using “limited dissolve” (select stuff, press x) can make level triangles turn (back?) into quads, which is better for selection
    • Using “m” or auto merge can reduce the vertices of curves. You can change the threshold for auto merge, and it only applies to stuff you actually move, so if you want some specific pieces to simiplify just select them and press “g” and then “0” to move them no where, activating auto merge. Be careful to keep pieces separate; this will help you later.
    • Decimate. The. Mesh. Do so in the properties tab; Modifiers -> add modifier -> generate -> decimate. The bar-value thing is how much to keep; I found 40% (0.4) changed very little of the geometry, even on the gears, but still reduced vertices to 40% of the original value.
  3. You can use ctrl-J to join two meshes together; this can put the gripper pieces back together and combine the gripper with the main mesh. Order of selection should only matter for things not relevant to this tutorial.

Materials were added to each segment of the arm, with most of the gripper being one material.

Exporting

Make sure the thing you are exporting is at the origin. The offset will be taken into account when it is packaged.

Go to file -> export -> .fbx (for meshes, and not the experimental one)

I suggest using “Include” -> limit to -> “selected objects” and changing object types to just “mesh.” Also change “Forward” to Z forward rather than -Z. You can save these presets for later use.

Importing into Unreal

In the content browser, select “import.” I imported it as a static mesh and converted it, but may work better to import it as a skeletal mesh. tip: at least with the static mesh, you can use a reimport button to have unreal reimport the asset from the same file location. Good if you make some changes to the blender version and re-export. Noteworthy that it does not affect the skeletal mesh you create off it. Untested on importing and then reimporting for the skeletal mesh, but other experience found nonsensical conflicts. Unreal truly is one of the Game Engines of all time.

Should be done as quick as that, though if you experience a bug (crash level) with weight painting later, you may want to see the entry on bugs.

Controlling the Arm

|++++|++++|-|_|-|_|-|_|-Construction-|_|-|_|-|_|++++|++++| For 2025, the arm was controlled by an xbox controller with the following keybinds;

Additionally, for use with only a keyboard, the following bindings were placed;

Finally, the following keys were used for extra features;

The arm has several pieces.

What was done;

What’s done where;

How to;

What was done;

Static mesh, Skeleton, Skeletal Mesh

Control Rig

Animation Blueprint

General Settings

Blueprint

Physics

Extra Notes;

|++++|++++|-|_|-|_|-|_|-Construction-|_|-|_|-|_|++++|++++|

Extra Things

Out of Order Changes

If you alter the original mesh, you can right-click on the mesh in unreal and reimport it. May not update things based on it, however. If you make a change to the skeleton after creating the control rig, right-click on the Root bone (the total parent bone) -> Assets (section) -> Refresh -> select the skeletal mesh.

Venting and bugs

Process Location: Importing the created mesh, weight paint the mesh

Issue:

Unreal Crashes after pressing accept on weight painting. To be specific, it gives an error message of an “index out of range” error; its not very specific as to what it applies to, but it is the basic “list is # elements, list[#] does not exist (b/c 0 is the first entry, so # is the first entry out of range)” Only occurs when you click “accept” after weight painting. Uploading seems uneffected.

Understanding:

Importing and w-painting different objects was successful. Led to finding that it wasn’t the file. Importing and w-painting the same object but with pieces removed was successful. Led to finding that it was specific geometry that was the problem.

Resolution:

Geometry fixed on bicep and the gripper’s actual gripping surface. Gears also had problematic geometry, but were too complicated to disconnect and sift through, so they were instead deleted. May be left over materials in blend and uasset files.