Skip to content

Setup

Adding the Robot

The 3D file of the X-Arm 5 provided by the manufacturer is a .STEP CAD file. To port this model into Unreal Engine, use the Datasmith CAD Importer plugin. Select the Quickly add to the project menu, and then File Import under Datasmith. Use the default options.

Datasmith import menu

It will be added to your open map, or a new one if none was open.

Select all actors under xArm5_XF1300_

Select Actors

Convert selection to a Blueprint class

Make new blueprint class

Select Harvest Components, and make the parent class a Pawn. Name it “X-Arm5”

Harvest Components

Assembly

Open the newly created Pawn Blueprint for the XArm.

We are going to rename the static mesh components to make the imported names more clear. The imported meshes in the content drawer should be identical:

Static Meshed in Content

Follow the table below to rename each of the components we are going to use. Delete any static meshes not included here.

Component Naming Table

Static Mesh Component New NameOld Name
J1EaEe1
J2EaEe1_3
J3aNONE_SAFE_5
J3bNONE_SAFE_7
J4aEaEe1_2
J4bEaEe2
J5NONE_SAFE
J6NONE_SAFE_4

For each scene group (J1_J1, J2_J2, …, Tool_head_Tool_head) that contain the meshes, add corresponding Physics Constraint components named C1, C2, etc., except for C6.

Your component menu should look similar to the following now. Order does not matter.

Components renamed

Configuration

Now, we need to setup the meshes & constraints to have the proper physics setup for the robot to behave correctly.

Meshes

The meshes do not have a collision mesh by default when imported via Datasmith, so we need to configure these manually in order to use phyiscs on the robot. To do this, go to the location in the Content Drawer where the meshes were imported, and follow this table to configure the collisions.

You only need to change the collision on the static meshes we are using, reference these from the assembly-components section.

Static MeshCollision TypeSimple Collision Physical MaterialCollision Presets
EaEe126DOP SimplifiedNonSlipperyBlockAll
All other 726DOP SimplifiedNonePhysicsActor

Your collsions should look like this for EaEe1:

EaEe1 mesh collision

and like this for the others:

Other mesh collisions

Note: If you don’t see NonSlippery as an option, this is a part of the starter content - an option that can be selected when creating the uproject

Head back to the X-Arm5 Blueprint, and setup the following options on each static mesh component:

  1. For J1, set the following under Constraints J1 Mesh Constraints

  2. For J6, set the following under Constraints J6 Mesh Constraints

  3. Set Linear & Angular damping to 5.0 for J1-6

  4. We need to ensure the parts do not interfere with each other. To do so, we need to alternate the object type in the collision presets. Follow the table to configure this.

    • Each mesh should have the Collision Presets set to Custom… and the Collision Enabled set to Collision Enabled (Query and Physics)

    • On meshes that are of type linkA, set linkA to Block and linkB to Ignore under Collision Responses

    • Conversely, meshes of type linkB should have linkA set to Ignore and linkB to Block

Static Mesh ComponentObject Type
J1linkA
J2linkB
J3alinkA
J3blinkB
J4alinkA
J4blinkB
J5linkA
J6linkB

The mesh collision presets menus should look like the following now: Collision presets for linkA

Collision presets for linkB

  1. Turn on Simulate Physics for J2-6. Leave it off for J1
  2. Turn off Enable Gravity for J1-6

Constraints

Each piece of the arm needs to be connected to the next corresponding piece, as well as having its motion restricted to only the directions allowed by the physical robot.

  1. For each C1-C5, set Component Name 1 to the corresponding mesh, and Component Name 2 to the next mesh (i.e. for C1, Component Name 1 is J1, and Component Name 2 is J2, etc.)

    • Be sure that C3a connects J3a and J3b, and likewise for C4a
  2. Set the Linear Limits to Locked in each axis, for each physics constraint component

  3. Set the Angular Limits as described in the table:

Physics ConstraintSwing 1 MotionSwing 2 MotionTwist Motion
C1FreeLockedLocked
C2, C3b, C4bLockedFreeLocked
C3a, C4a, C5LockedLockedLocked
  1. Set the Angular Drive Mode according to the table:
Physics ConstraintAngular Drive Mode
C1, C2, C3b, C4bTwist and Swing
C3a, C4a, C5SLERP

Functionality

Variables

Add the following variables:

  • Links (Static Mesh Component Array)

  • Constraints (Physics Constraint Component Array)

  • LinkTransforms (Transform Array)

It should look like this now

Agent Variables

Functions

  1. Set the function EventGraph as follows

  2. Create a function ResetLocation, and wire it as follows

Creating the Target Blocks

  • Inside Unreal Editor, go to tools -> New C++ Class

  • Select Actor

  • Keep the class type public, and title it “PickBlock”

  • Code has been provided for PickBlock.h/.cpp. Paste it accordingly in the new files

  • Compile the project.

Now, back in the editor, open the Content Drawer and locate the PickBlock C++ class that was created. Right click and select “Create Blueprint class based on PickBlock”. Title it “BP_PickBlock” and place it where the X-Arm5 blueprint is stored. Next, we are going to create a custom material to provide color to the target blocks.

  • Create a new material titled “M_Goal_Unlit”

  • Open the material editor

  • Change the Shading Model to Unlit

  • In the material graph, add a Vector Parameter titled “Color”. Set its default value to (1.0, 0.0, 1.0, 1.0) in RGBA.

  • Add a Scalar Parameter titled “Intensity” and set its default value to 10.0.

  • Then wire it all as so to complete the material

Material Graph

Now, back in BP_PickBlock, we need to set some parameters:

  • Static Mesh is set to Shape_Sphere

  • Under Materials, replace the default with M_Goal_Unlit

  • Change the Collision Presets to match the following:

Collision Presets

  • Scroll down to the Pick Block section

  • Under Materials, set the Red, Yellow, and Blue materials to M_Goal_Unlit.

Creating the Environment

  1. Create a new blueprint labeled “BP_XArmEnv”

    • When the popup window opens, drop down “All Classes” and search for “Gym”

    • Select the Gym Connector Manager

  2. Go to Class Settings

    • Under Interfaces, go to Implemented Interfaces

    • Search for and add Single Agent Schola Environment

    • The interfaces should be populated with five items now.

As we did for PickBlock, we are going to need to add two new C++ files.

  • Call them “XArmEnvComponent”, keep them public and in the same location as the PickBlock source files.

  • Paste in the provided code for XArmEnvComponent.h/.cpp

  • Compile these changes, and reopen Unreal Engine

  • In the components menu, add a new component by searching for XArm, select XArm Env. Call it “XArmEnvComp”

Add the following variables:

Env Variables

Now, under interfaces, double click on SetEnvironmentOptions and SeedEnvironment. They should both show up in the EventGraph. Then, wire them both up as follows:

We have several functions to setup now. Follow the Blueprints to set them up

  • ComputeReward

  • ComputeStatus

  • Step

  • Reset

  • InitializeEnvironment

  • GetObservationSpace

  • CollectObservations

  • GetActionSpace

  • ApplyAction

World Setup

  • Place the X-Arm5 in the world and label it “Agent1”

  • BP_XArmEnv inside the world, with the actor for the environment placed at the base of the robot.

  • In the world editor, select the BP_XArmEnv

    • Set Agent to Agent1

Your world should now look similar to the following on pressing the play button

Initial stage