A design with components and joints exports as a URDF robot description (file.export to .urdf, the MCP export tool, solidcraft-cli run --out, File > Export URDF...). It writes one binary STL per component in metres, links with mass, centre of mass and inertia from material density, and maps rigid, revolute, slider, cylindrical, pin-slot, planar and ball joints to URDF joints or short chains. Loops, broken joints and loose parts are reported as warnings. Options: mesh_prefix, effort, velocity. Docs in docs/urdf.md.
This commit is contained in:
1 parent
d2e409f40c
commit
17db109c5d
19 files changed
+1993
-17
No files matched your search
@@ -8,6 +8,7 @@
|
||||
| IGES 5.3 | manifold solids, or trimmed surfaces sewn into solids | manifold solids with names and colours |
|
||||
| 3MF, STL, OBJ | mesh bodies | yes |
|
||||
| 3MF with face tags | as 3MF | each triangle tagged with its B-rep face, exact coordinates |
|
||||
| URDF | | the assembly as a robot: links with meshes, mass and inertia, joints from the assembly's joints |
|
||||
| DXF, SVG | into a sketch | sketches and flat patterns as DXF |
|
||||
| PNG, JPEG | canvases and decals | |
|
||||
|
||||
@@ -35,6 +36,11 @@ is the tessellation's own double-precision value. Meshing and analysis tools can
|
||||
keep a model's faces (for loads, boundary conditions or feature edges); other 3MF readers ignore
|
||||
them. The format is specified in [`docs/formats/3mf-face-tags.md`](https://github.com/bherbruck/solidcraft/blob/main/docs/formats/3mf-face-tags.md).
|
||||
|
||||
**File → Export URDF…** (`file.export` with a `.urdf` path) writes the assembly for robot
|
||||
simulators and ROS: a link per component placement with its mesh, mass and inertia, and the
|
||||
assembly's joints, so the parts move in the simulator as they do in SolidCraft. The meshes are
|
||||
written as STL files next to the `.urdf`. See [`docs/urdf.md`](https://github.com/bherbruck/solidcraft/blob/main/docs/urdf.md).
|
||||
|
||||
Saves are atomic: a crash at any moment leaves either the old file or the new one, and the
|
||||
replaced version is kept as `<file>.bak`. A save keeps the file's permissions, and a design
|
||||
opened through a symbolic link (a synced folder linked into a project) is saved into the file the
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ They cover the workflow, the command shapes, how to verify with `measure`, and t
|
||||
| `body_topology` | `body` | Edges (index, midpoint, length, ends) and faces (index, area, centroid, normal). An edge midpoint is the `[x,y,z]` that picks that edge for fillet and chamfer. |
|
||||
| `set_parameter` | `name`, `value` (number or expression), `unit?`, `comment?` | Create or change a user parameter and recompute; reports `recomputed` (features rebuilt), `restored` (features whose earlier result for the same inputs was reused, e.g. a value set back) and features that now fail. |
|
||||
| `screenshot` | `view?` (iso, top, front, back, bottom, left, right, home, fit, or a named view saved with `view.save`), `camera?` (`{target, yaw, pitch, distance, fov?}`, as `view.apply`), `path?`, `width?`, `height?`, `source?` (window, model) | A PNG image content block. Headless: CPU render fitted to the model, or from the named view or camera. Bridged: the app window (default) or a model render with the app's camera; a named view or camera moves the app's viewport there first (`execute` `view.apply` does the same without a screenshot). |
|
||||
| `export` | `path`, `format?` (step, 3mf, 3mf-tagged, stl, stla, obj), `bodies?` | STEP, 3MF or mesh export. |
|
||||
| `export` | `path`, `format?` (step, 3mf, 3mf-tagged, stl, stla, obj, urdf), `bodies?`, `mesh_prefix?`, `effort?`, `velocity?` | STEP, 3MF or mesh export; URDF writes the whole assembly with its meshes next to it (`docs/urdf.md`). |
|
||||
| `undo`, `redo` | — | Undo / redo one change. |
|
||||
| `crash_reports` | `id?`, `limit?` | The crash reports on this computer, newest first; with `id`, the whole report (backtrace, command, recent commands, `design_path`/`replay_path`). See [crash-reports.md](crash-reports.md). |
|
||||
| `new_design` | `name?` | Start an empty design. |
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
# URDF export
|
||||
|
||||
A design with components and joints exports as a robot description in URDF (Unified Robot
|
||||
Description Format), the format ROS, Gazebo, Isaac Sim, PyBullet and MuJoCo read. Each part
|
||||
becomes a link with its mesh, mass and inertia. Each joint becomes a URDF joint, or a short
|
||||
chain of them, that moves the parts the way SolidCraft does.
|
||||
|
||||
- **Desktop:** **File → Export URDF…**
|
||||
- **Commands:** `file.export {"path": "robot.urdf"}` (or `"format": "urdf"`)
|
||||
- **MCP:** the `export` tool with a `.urdf` path or `format: "urdf"`
|
||||
- **CLI:** `solidcraft-cli run script.json --out robot.urdf`
|
||||
|
||||
URDF always exports the whole assembly, so `bodies` is refused.
|
||||
|
||||
## Files
|
||||
|
||||
Next to `robot.urdf` the export writes one binary STL per component, in metres:
|
||||
|
||||
- `robot-<component>.stl` holds all of the component's bodies. The root component's bodies go
|
||||
in `robot-base.stl`.
|
||||
- `robot-<component>-collision.stl` appears only when a component mixes closed solids with
|
||||
open surfaces: it holds the closed ones, which are the collision geometry.
|
||||
|
||||
Every path is checked before anything is written, including against the folders an agent may
|
||||
use (`allow_paths`). The meshes are written first and the `.urdf` last. If a write fails part
|
||||
way, the error names the files already written and the one that failed.
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Default | Meaning |
|
||||
|---|---|---|
|
||||
| `mesh_prefix` | none | Put before each mesh file name. Leave it empty for loaders that resolve against the URDF's folder (Isaac Sim, PyBullet, MuJoCo, yourdfpy). RViz and other ROS tools need `package://<pkg>/meshes/` or an absolute folder. |
|
||||
| `effort` | 1000 | Joint effort limit, in N (sliding) or N m (turning). |
|
||||
| `velocity` | 10 | Joint velocity limit, in m/s or rad/s. |
|
||||
|
||||
URDF requires `effort` and `velocity` on every moving joint. When they are not given, the
|
||||
defaults are written and a warning says so. A value that is not a positive number is refused.
|
||||
|
||||
## Links
|
||||
|
||||
- **`base_link`** holds the root component's bodies and stays fixed in the world. Every
|
||||
grounded occurrence hangs on it by a `fixed` joint at its current place.
|
||||
- **One link per placement of a component.** A component placed once gives its name to the
|
||||
link (`Gripper`). One placed several times gives the occurrence names (`Finger:1` becomes
|
||||
`Finger_1`).
|
||||
- **Names** use only `A-Z a-z 0-9 _` (mesh files also keep `-`). Links, joints and files share
|
||||
one set of names, because Gazebo refuses a link and a joint with the same name. A name
|
||||
already taken gets `_2`, `_3` and so on. Joint names are taken first, so a joint keeps the
|
||||
name you gave it. Mesh file names are compared without case, since Windows and macOS ignore
|
||||
it.
|
||||
- **Mass and inertia** come from each body's mesh and material density: the mass in kg, the
|
||||
centre of mass and the inertia tensor about it in the link frame, in kg m². Bodies of the
|
||||
same link combine with the parallel-axis theorem.
|
||||
- **Open surfaces** are drawn but add no mass or collision, with a warning naming them.
|
||||
- **A link with no mass** (only surfaces, no bodies, or a chain's in-between link) gets a token
|
||||
mass of 1e-6 kg and inertia of 1e-12 kg m², because Gazebo drops massless links and breaks
|
||||
the chain there.
|
||||
- **Colour:** the first body's colour, as the visual's material.
|
||||
|
||||
## Joints
|
||||
|
||||
| SolidCraft joint | URDF |
|
||||
|---|---|
|
||||
| Rigid | `fixed` |
|
||||
| Revolute | `revolute` about z with limits, or `continuous` without |
|
||||
| Slider | `prismatic` along z |
|
||||
| Cylindrical | `revolute` z, then `prismatic` z |
|
||||
| Pin-slot | `prismatic` x, then `revolute` z |
|
||||
| Planar | `prismatic` x, `prismatic` y, then `revolute` z |
|
||||
| Ball | `revolute` z, `revolute` y, then `revolute` z |
|
||||
|
||||
- **Chains:** a joint with several values becomes one URDF joint per value. Between them sit
|
||||
links named `<joint>_link1`, `<joint>_link2`. The steps before the last are named
|
||||
`<joint>_dof1`, `<joint>_dof2`, and the last one keeps the joint's name.
|
||||
- **Values:** each URDF joint value equals the SolidCraft value it comes from: the same angle
|
||||
(in radians) or distance (in metres). This holds whichever side of the joint is nearer the
|
||||
base. When the tree reaches a joint from its B side, the chain runs backwards with its axes
|
||||
reversed, so the values still match.
|
||||
- **Limits** are written as `lower <= upper` in radians or metres. A sliding step without a
|
||||
limit gets ±1000 m, since URDF requires one, with a warning.
|
||||
- **Motion links** are not written as `<mimic>`. Each joint's own value is free in the URDF.
|
||||
|
||||
The URDF is written at the design's current joint values, with every part where it is shown,
|
||||
including moves not captured yet. The exception is a part the joints place: it exports where its
|
||||
joints put it, since they put it back as soon as one moves, and a warning says so. Moving a joint in a simulator puts
|
||||
the parts the joint solver places where SolidCraft's **Drive Joints** would.
|
||||
|
||||
## The tree
|
||||
|
||||
URDF is a tree hanging from `base_link`. The export builds it the way the joint solver walks
|
||||
the assembly.
|
||||
|
||||
1. From `base_link` and the grounded occurrences, it follows the joints outwards.
|
||||
2. A group of parts joined to each other but to nothing grounded is fixed where it is by the
|
||||
A side of its first joint, as the solver does when nothing is grounded. A warning says the
|
||||
part is not grounded.
|
||||
3. A part no joint reaches is fixed where it is. A nested one hangs on its parent part, so it
|
||||
moves with it, as in SolidCraft. A top-level one hangs on `base_link`, with a warning.
|
||||
4. A joint that would close a loop is left out, with a warning, since a tree cannot hold it.
|
||||
5. A joint whose snap points no longer resolve (for example, the face it was on is gone) is
|
||||
left out, with a warning naming it.
|
||||
|
||||
When a component is placed several times, what is nested in it appears in each placement. In
|
||||
the URDF the first placement is the one its joints move; the others are copies fixed in their
|
||||
parent at their current pose, with a warning when the copied part has a joint. (In SolidCraft
|
||||
the copies move together, which a URDF could only express with `<mimic>`.) The export stops copying past
|
||||
64 levels or 100 000 placements, with a warning.
|
||||
|
||||
## Not covered
|
||||
|
||||
- `<mimic>` for motion links.
|
||||
- Simplified collision shapes: the collision mesh is the visual mesh.
|
||||
- SDF and MJCF export, and URDF import.
|
||||
- Joint motion inside the copies of a component placed several times.
|
||||
- Drive dynamics: `effort` and `velocity` are limits you choose.
|
||||
Reference in new issue
Block a user