Agent skill

Configure Joint Articulation

by lge-ros2 in lge-ros2/cloisim

Configure Unity ArticulationBody joints from SDF joint definitions.

MITAuto-check passedGame Development

Install Configure Joint Articulation

skills CLI
$ npx skills add lge-ros2/cloisim --skill configure-joint-articulation -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install lge-ros2/cloisim configure-joint-articulation --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/lge-ros2/cloisim.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/configure-joint-articulation .claude/skills/configure-joint-articulation && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
configure-joint-articulation
GitHub stars
176
Token cost
~2.7k tokens
SKILL.md length
471 words
Files
1
Skills in repo
18
Repo updated
First seen
Licence
MIT

At a glance

Configure Unity ArticulationBody joints from SDF joint definitions.

  • Works in 5 steps: Import Phase — Link Resolution and… → Parent-Child Hierarchy Setup → Joint Type Configuration → …
  • : adding a new joint type
  • SKILL.md covers When to Use, Architecture, Joint Type Reference and Procedure, plus 2 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Configure Joint Articulation is an agent skill from lge-ros2/cloisim. Configure Unity ArticulationBody joints from SDF joint definitions. Use when: adding a new joint type, debugging joint axis alignment, tuning spring/damping/limits, fixing revolute or prismatic joint behavior, setting up parent-child articulation hierarchy.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Game Development. The repository describes itself as: Unity 6 based multi-robot simulator for ROS 2, SDFormat/SDF, LiDAR, camera, depth, IMU, GPS, and large-scale robotics simulation. The licence is MIT.

When your agent uses it

  • : adding a new joint type
  • Debugging joint axis alignment
  • Tuning spring/damping/limits
  • Fixing revolute

Example prompts

  • “/configure-joint-articulation”

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Import Phase — Link Resolution and Hierarchy
  2. Parent-Child Hierarchy Setup
  3. Joint Type Configuration
  4. Helper.Link Metadata
  5. Adding a New Joint Type

What it can do on your machine

Read from SKILL.md and the folder at commit f4c1f0b. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are csharp).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Configure Joint Articulation loads about 2.7k tokens when it runs. Until then it costs about 72 tokens; SKILL.md has 471 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~72
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from lge-ros2/cloisim at commit f4c1f0b, republished under its MIT licence (© lge-ros2). 471 words, ~2,660 tokens.

Download SKILL.mdSave it as .claude/skills/configure-joint-articulation/SKILL.md (or your agent's skills folder).
name
configure-joint-articulation
description
Configure Unity ArticulationBody joints from SDF joint definitions. Use when: adding a new joint type, debugging joint axis alignment, tuning spring/damping/limits, fixing revolute or prismatic joint behavior, setting up parent-child articulation hierarchy.

Configure Joint Articulation

Reference and procedure for configuring Unity ArticulationBody joints from SDF <joint> definitions. Covers the full import → implement flow, joint type dispatch, axis alignment, drive configuration, and limit handling.

When to Use

  • Adding support for a new SDF joint type (e.g., gearbox, screw)
  • Debugging incorrect joint axis orientation or motion direction
  • Tuning spring stiffness, damping, friction, or force limits
  • Fixing revolute joint limit inversion issues
  • Setting up parent-child ArticulationBody hierarchy for a new robot model
  • Understanding how SDF joint parameters map to Unity ArticulationDrive

Architecture

SDF <joint>
  │
  ├─ Import.Joint.cs: ImportJoint()
  │  ├─ Resolve parent/child links by name
  │  ├─ Create ArticulationBody on child link
  │  ├─ Call Implement.Joint methods
  │  └─ Store joint metadata on Helper.Link
  │
  └─ Implement.Joint.cs: MakeJoint()
     ├─ SetArticulationBodyRelationship() → parent-child hierarchy + anchor pose
     ├─ SetAnchor() → anchor position/rotation
     └─ Type dispatch:
        ├─ Revolute/Continuous → MakeRevoluteJoint()
        ├─ Prismatic → MakePrismaticJoint()
        ├─ Ball → MakeBallJoint()
        ├─ Universal/Revolute2 → MakeRevoluteJoint2()
        └─ Fixed → MakeFixedJoint()

Joint Type Reference

SDF TypeUnity TypeDOFNotes
revoluteSphericalJoint (1-DOF locked)1 rotationalLimits via CurveOrientation swap
continuousSphericalJoint (1-DOF free)1 rotationalNo limits, free rotation
prismaticPrismaticJoint1 linearDirect limit mapping (no swap)
ballSphericalJoint (3-DOF free)3 rotationalAll axes free
universal / revolute2SphericalJoint (2-DOF)2 rotationalTwo-axis via MakeRevoluteJoint2()
fixedFixedJoint0Zero solver iterations

Procedure

Import.Joint.cs resolves parent/child links by name and establishes the ArticulationBody hierarchy:

csharp
// Link resolution — searches by name in the model hierarchy
var linkObjectParent = targetObject.FindTransformByName(joint.ParentName);
var linkObjectChild = targetObject.FindTransformByName(joint.ChildName);

// Create ArticulationBody if not present
var articulationBodyChild = linkObjectChild.GetComponent<ArticulationBody>();
if (articulationBodyChild == null)
	articulationBodyChild = CreateArticulationBody(linkObjectChild.gameObject);

// Establish parent-child and compute anchor pose
var anchorPose = Implement.Joint.SetArticulationBodyRelationship(
	joint, linkObjectParent, linkObjectChild);
articulationBodyChild.SetAnchor(anchorPose);

// Configure joint type
articulationBodyChild.MakeJoint(joint);
2. Parent-Child Hierarchy Setup

SetArticulationBodyRelationship() decides hierarchy based on model scope:

csharp
// Same model → child link becomes child of parent link
linkChild.SetParent(linkParent);

// Cross-model → child model root becomes child of parent link
modelTransformChild.SetParent(linkParent);

// Anchor pose starts at identity, then adds joint pose offset
var (jointPos, jointRot) = joint.RawPose.ToUnity();
anchorPose.position += jointPos;
anchorPose.rotation *= jointRot;
3. Joint Type Configuration
Revolute Joint

Uses SphericalJoint with two axes locked. Key pattern: limit values are swapped through SDF2Unity.CurveOrientation():

csharp
private static void MakeRevoluteJoint(this ArticulationBody body, in JointAxis axis)
{
	body.jointType = ArticulationJointType.SphericalJoint;
	body.linearDamping = 1.5f;
	body.angularDamping = 2f;

	var drive = new ArticulationDrive();

	// CRITICAL: Limits are swapped via CurveOrientation
	if (axis.HasJointLimits())
	{
		drive.lowerLimit = SDF2Unity.CurveOrientation((float)axis.Upper); // Upper → lower
		drive.upperLimit = SDF2Unity.CurveOrientation((float)axis.Lower); // Lower → upper
	}

	drive.forceLimit = double.IsInfinity(axis.Effort)
		? float.MaxValue : (float)axis.Effort;
	drive.stiffness = (float)axis.SpringStiffness;
	drive.target = SDF2Unity.CurveOrientation((float)axis.SpringReference);
	drive.damping = (float)axis.Damping;

	body.jointFriction = (float)axis.Friction;
	body.maxJointVelocity = (float)axis.MaxVelocity;

	// Axis alignment — determines which DOF is active
	var jointAxis = axis.Xyz.ToUnity().normalized;
	// Assign to xDrive/yDrive/zDrive based on dominant axis component
}
Axis Alignment Pattern

The dominant axis component determines which drive and DOF lock to use:

csharp
var absX = Mathf.Abs(jointAxis.x);
var absY = Mathf.Abs(jointAxis.y);
var absZ = Mathf.Abs(jointAxis.z);

if (absX >= absY && absX >= absZ)
{
	// X-dominant: rotate anchor to align, use xDrive
	body.anchorRotation *= Quaternion.FromToRotation(Vector3.right, jointAxis);
	body.xDrive = drive;
	body.twistLock = hasLimits
		? ArticulationDofLock.LimitedMotion : ArticulationDofLock.FreeMotion;
	body.swingYLock = ArticulationDofLock.LockedMotion;
	body.swingZLock = ArticulationDofLock.LockedMotion;
}
else if (absY >= absX && absY >= absZ)
{
	// Y-dominant: use yDrive, lock twist and swingZ
	body.anchorRotation *= Quaternion.FromToRotation(Vector3.up, jointAxis);
	body.yDrive = drive;
	body.twistLock = ArticulationDofLock.LockedMotion;
	body.swingYLock = hasLimits
		? ArticulationDofLock.LimitedMotion : ArticulationDofLock.FreeMotion;
	body.swingZLock = ArticulationDofLock.LockedMotion;
}
else
{
	// Z-dominant: use zDrive, lock twist and swingY
	body.anchorRotation *= Quaternion.FromToRotation(Vector3.forward, jointAxis);
	body.zDrive = drive;
	body.twistLock = ArticulationDofLock.LockedMotion;
	body.swingYLock = ArticulationDofLock.LockedMotion;
	body.swingZLock = hasLimits
		? ArticulationDofLock.LimitedMotion : ArticulationDofLock.FreeMotion;
}
Prismatic Joint

Linear motion — limits are not swapped (unlike revolute):

csharp
private static void MakePrismaticJoint(this ArticulationBody body, in JointAxis axis)
{
	body.jointType = ArticulationJointType.PrismaticJoint;

	var drive = new ArticulationDrive();

	// Direct limit mapping (no CurveOrientation swap)
	if (axis.HasJointLimits())
	{
		drive.lowerLimit = (float)axis.Lower;
		drive.upperLimit = (float)axis.Upper;
	}

	drive.target = (float)axis.SpringReference; // No CurveOrientation
	// ... same force/stiffness/damping pattern as revolute

	// Axis alignment uses linearLockX/Y/Z instead of twist/swing
	if (absX >= absY && absX >= absZ)
	{
		body.xDrive = drive;
		body.linearLockX = hasLimits
			? ArticulationDofLock.LimitedMotion : ArticulationDofLock.FreeMotion;
		body.linearLockY = ArticulationDofLock.LockedMotion;
		body.linearLockZ = ArticulationDofLock.LockedMotion;
	}
	// ... similar for Y and Z
}
Other Joint Types
csharp
// Ball — 3-DOF free rotation
body.jointType = ArticulationJointType.SphericalJoint;
body.swingYLock = ArticulationDofLock.FreeMotion;
body.swingZLock = ArticulationDofLock.FreeMotion;
body.twistLock = ArticulationDofLock.FreeMotion;

// Fixed — no motion, zero solver iterations
body.jointType = ArticulationJointType.FixedJoint;
body.solverIterations = 0;
body.solverVelocityIterations = 0;

// Revolute2/Universal — apply axis1 then overlay axis2
MakeRevoluteJoint(body, axis1);
// Override second DOF with axis2 parameters

After joint creation, the importer stores metadata on Helper.Link for runtime use:

csharp
var linkHelper = linkObjectChild.GetComponent<Helper.Link>();
linkHelper.JointName = joint.Name;
linkHelper.JointParentLinkName = joint.ParentName;
linkHelper.JointChildLinkName = joint.ChildName;

// Axis orientation conversion differs by joint type
if (joint.Type == JointType.Prismatic)
	axisSpringReference = (float)joint.Axis.SpringReference; // Direct
else
	axisSpringReference = SDF2Unity.CurveOrientation(...);    // Curve transform

linkHelper.SetJointPoseTarget(axis1xyz, axisSpringReference,
	axis2xyz, axis2SpringReference);
5. Adding a New Joint Type

To add support for an unsupported joint type (e.g., screw, gearbox):

  1. Add a case in MakeJoint() dispatch:

    csharp
    case JointType.Screw:
        body.MakeScrewJoint(joint.Axis);
        break;
  2. Create the implementation method:

    csharp
    private static void MakeScrewJoint(this ArticulationBody body, in JointAxis axis)
    {
        // Choose appropriate ArticulationJointType
        // Configure drives, limits, damping
        // Handle axis alignment
    }
  3. Decide limit semantics: revolute-style (swap via CurveOrientation) or prismatic-style (direct).

Show full SKILL.md (189 more words)Show less

Critical Rules

  1. Revolute limits are always swapped — lowerLimit = CurveOrientation(Upper), upperLimit = CurveOrientation(Lower). This accounts for the SDF→Unity coordinate handedness change.
  2. Prismatic limits are never swapped — direct mapping from SDF values.
  3. Axis alignment — always use axis.Xyz.ToUnity().normalized for coordinate conversion, then select drive by dominant component.
  4. Anchor rotation — Quaternion.FromToRotation() aligns the drive axis to the joint axis direction.
  5. Continuous joints have no limits — use ArticulationDofLock.FreeMotion instead of LimitedMotion.
  6. Force limits — check double.IsInfinity(axis.Effort) and map to float.MaxValue.

Common Issues

SymptomCauseFix
Joint rotates on wrong axisDominant axis detection chose wrong componentCheck axis.Xyz in SDF, verify .ToUnity() conversion
Joint hits limits at wrong anglesLimit swap not applied (or applied to prismatic)Revolute: must swap. Prismatic: must not swap
Joint doesn't moveAll DOFs lockedVerify at least one lock is FreeMotion or LimitedMotion
Child link flies awayMissing ArticulationBody on parent chainEnsure all links from root to child have ArticulationBody
Spring target wrong directionCurveOrientation not applied to spring referenceRevolute targets need CurveOrientation; prismatic do not
Cross-model joint breaks hierarchyWrong parent chosen in SetArticulationBodyRelationshipCheck model scope logic in import phase

© lge-ros2, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .github/skills/configure-joint-articulation of lge-ros2/cloisim.

Open the folder on GitHubat commit f4c1f0b

Compare with similar skills

Configure Joint Articulation next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Configure Joint Articulation compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Configure Joint Articulation this skilllge-ros2/cloisim176—~2.7kAutomated safety check: PassMIT
Dev StoryDonchitos/Claude-Code-Game-Studios26k—~2.4kAutomated safety check: NotesMIT
Blockbench Pluginsjasonjgardner/blockbench-mcp-plugin500—~2.8kAutomated safety check: PassGPL-3.0
Portal Connectgosuda/portal-tunnel308—~2.9kAutomated safety check: PassMIT
Aibridge Development WorkflowFlameskyDexive/Legends-Of-Heroes928—~790Automated safety check: PassMIT
Designvladikk/modularity555—~3.8kAutomated safety check: PassCustom licence

Similar skills

  • Dev Story

    Donchitos/Claude-Code-Game-Studios

    Implement a story: ADR guidelines, right programmer agent, code plus test.

    26k GitHub stars~2.4k tokensUpdated 3 days ago
    Game DevelopmentAuto-check: notes
  • Blockbench Plugins

    jasonjgardner/blockbench-mcp-plugin

    Blockbench plugin/extension development for the 3D modeling tool.

    500 GitHub stars~2.8k tokensUpdated 9 days ago
    Game DevelopmentAuto-check passed
  • Portal Connect

    gosuda/portal-tunnel

    Reach, inspect, or consume a service that someone published through a Portal relay.

    308 GitHub stars~2.9k tokensUpdated today
    Game DevelopmentAuto-check passed
  • Aibridge Development Workflow

    FlameskyDexive/Legends-Of-Heroes

    AIBridge/Unity 项目的标准开发工作流。Use when creating, modifying, fixing, refactoring, or validating C code, Unity assets, prefabs, editor tools, package structure, tests, AGENTS.md, or local Skills.

    928 GitHub stars~790 tokensUpdated 19 days ago
    Game DevelopmentAuto-check passed
  • Design

    vladikk/modularity

    Designs modular high-level architectures from functional requirements and produces design documents for each module.

    555 GitHub stars~3.8k tokensUpdated 1 mo ago
    Game DevelopmentAuto-check passed
  • Sokol Net

    elix22/Sokol.NET

    Sokol.NET framework development — use for ANY work in this repo: creating or debugging examples, building/running for desktop/Android/iOS/Web, writing or compiling shaders, adding a new C/C++…

    154 GitHub stars~2.8k tokensUpdated yesterday
    Game DevelopmentAuto-check passed

More from lge-ros2/cloisim

All 18 skills in this repo
  • Add Actor Animation

    lge-ros2/cloisim

    Add or modify SDF actors with skeletal animation and waypoint-based navigation.

    176 GitHub stars~2.4k tokensUpdated 5 days ago
    Auto-check passed
  • Add Compute Shader

    lge-ros2/cloisim

    Add a new compute or surface shader for sensor data processing or visualization.

    176 GitHub stars~2.1k tokensUpdated 5 days ago
    Auto-check passed
  • Add Mesh Import

    lge-ros2/cloisim

    Import 3D mesh files into CLOiSim via the Assimp pipeline, including collision generation and procedural meshes.

    176 GitHub stars~2k tokensUpdated 5 days ago
    Auto-check passed
  • Add Motor Controller

    lge-ros2/cloisim

    Add a new motor or drive controller for robot locomotion. An agent skill from lge-ros2/cloisim.

    176 GitHub stars~1.4k tokensUpdated 5 days ago
    Auto-check passed
  • Add New Plugin

    lge-ros2/cloisim

    Add a new CLOiSimPlugin for bridging a device to the ROS 2 transport layer.

    176 GitHub stars~1.5k tokensUpdated 5 days ago
    Auto-check passed
  • Add New Sensor

    lge-ros2/cloisim

    Add a new sensor device to CLOiSim, including the Device subclass, SDF pipeline wiring, and transport plugin.

    176 GitHub stars~1.6k tokensUpdated 5 days ago
    Auto-check passed

Questions about Configure Joint Articulation

What does Configure Joint Articulation do?

Configure Unity ArticulationBody joints from SDF joint definitions. Configure Joint Articulation is an agent skill from lge-ros2/cloisim. Configure Unity ArticulationBody joints from SDF joint definitions.

When should I use Configure Joint Articulation?

Configure Joint Articulation fits situations like: : adding a new joint type; debugging joint axis alignment; tuning spring/damping/limits; fixing revolute.

How do I install Configure Joint Articulation in Claude Code?

Run `npx skills add lge-ros2/cloisim --skill configure-joint-articulation -a claude-code`. Or copy the skill folder (.github/skills/configure-joint-articulation in lge-ros2/cloisim) into .claude/skills/configure-joint-articulation in your project. Claude Code loads it when a task matches its description.

How do I install Configure Joint Articulation in Codex?

Run `npx skills add lge-ros2/cloisim --skill configure-joint-articulation -a codex`. Or copy the skill folder (.github/skills/configure-joint-articulation in lge-ros2/cloisim) into .agents/skills/configure-joint-articulation in your project. Codex loads it when a task matches its description.

Can I use Configure Joint Articulation in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add lge-ros2/cloisim --skill configure-joint-articulation -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/configure-joint-articulation, .gemini/skills/configure-joint-articulation, .github/skills/configure-joint-articulation and .opencode/skills/configure-joint-articulation in your project.

What does Configure Joint Articulation need to run?

SKILL.md names no scripts, command-line tools or credentials: Configure Joint Articulation is instructions for the agent only.

Does Configure Joint Articulation access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Configure Joint Articulation safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Configure Joint Articulation use?

Configure Joint Articulation is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Configure Joint Articulation use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Configure Joint Articulation?

Skills that share tags, products or a category with Configure Joint Articulation: Dev Story (Donchitos/Claude-Code-Game-Studios, 26k stars), Blockbench Plugins (jasonjgardner/blockbench-mcp-plugin, 500 stars), Portal Connect (gosuda/portal-tunnel, 308 stars) and Aibridge Development Workflow (FlameskyDexive/Legends-Of-Heroes, 928 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Configure Joint Articulation?

lge-ros2 (a GitHub organization) maintains it in lge-ros2/cloisim, which has 176 GitHub stars. The repository holds 18 skills in this directory. The repository was last updated on October 6, 2026.

Source: lge-ros2/cloisim on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.