Import upstream snapshot 80e710700aac9573a2230f74f7ce9e094833a0bc

Upstream: https://github.com/Rhoban/onshape-to-robot
Upstream-Commit: 80e710700aac9573a2230f74f7ce9e094833a0bc
Upstream-Branch: master
This commit is contained in:
Upstream Snapshot
2026-08-28 15:42:31 +08:00
commit bb87928bce
107 changed files with 16958 additions and 0 deletions
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.2 MiB

+4
View File
@@ -0,0 +1,4 @@
img.padding {
margin-bottom: 20px !important;
}
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 679 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 253 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 347 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

+20
View File
@@ -0,0 +1,20 @@
Cache
=====
Presentation
------------
In order to re-issue the same requests to the Onshape API, ``onshape-to-robot`` caches the result of most of the requests.
.. note::
All requests involving a **workspace** can't be cached, since they rely on live version that are subject to change.
Clearing the cache
------------------
You can clear the cache using the following command:
.. code-block:: bash
onshape-to-robot-clear-cache
+61
View File
@@ -0,0 +1,61 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'Onshape to robot'
copyright = '2025, Rhoban'
author = 'Rhoban'
# The full version, including alpha/beta/rc tags
release = 'latest'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = [
'css/custom.css',
]
master_doc = 'index'
+277
View File
@@ -0,0 +1,277 @@
Configuration (config.json)
===========================
Specific entries
----------------
Below are the global configuration entries.
You might also want to check out the following documentation for more specific entries:
* Exporters
* :doc:`URDF specific entries <exporter_urdf>`
* :doc:`SDF specific entries <exporter_sdf>`
* :doc:`MuJoCo specific entries <exporter_mujoco>`
* :doc:`Processors <processors>` can define their own specific entries
``config.json`` entries
-----------------------
Here is an example of complete ``config.json`` file, with details below:
.. code-block:: javascript
// config.json general options
// for urdf or mujoco specific options, see documentation
{
// Onshape assembly URL
"url": "https://cad.onshape.com/documents/11a7f59e37f711d732274fca/w/7807518dc67487ad405722c8/e/5233c6445c575366a6cc0d50",
// Output format: urdf or mujoco (required)
"output_format": "urdf",
// Output filename (default: "robot")
// Extension (.urdf, .xml) will be added automatically
"output_filename": "robot",
// Assets directory (default: "assets")
"assets_directory": "assets",
// If you don't use "url", you can alternatively specify the following
// The Onshape document id to parse, see "getting started" (optional)
"document_id": "document-id",
// The document version id (optional)
"version_id": "version-id",
// The workspace id (optional)
"workspace_id": "workspace-id",
// Element id (optional)
"element_id": "element-id",
// Assembly name to use in the document (optional)
"assembly_name": "robot",
// Onshape configuration to use (default: "default")
"configuration": "Configuration=BigFoot;RodLength=50mm",
// Robot name (default: "onshape")
"robot_name": "robot",
// Ignore limits (default: false)
"ignore_limits": true,
// Parts to ignore (default: {})
"ignore": {
// Ignore visual for visual
"part1": "visual",
"screw*": "visual",
// Ignore everything expect "leg" for collision
"*" : "collision"
"!leg": "collision"
},
// Whether to keep frame links (default: false)
"draw_frames": true,
// Override the color of all links (default: None)
"color": [0.5, 0.1, 0.1],
// Disable dynamics retrieval (default: false)
"no_dynamics": true,
// Whether to include configuration suffix to part (stl) files (default: true)
"include_configuration_suffix": false,
// Post import commands (default: [])
"post_import_commands" [
"echo 'Import done'",
"echo 'Do something else'"
],
// Custom processors
"processors": [
"my_project.my_custom_processor:MyCustomProcessor"
],
// Number of decimals to round numerical values (default: 12)
"round_decimals": 12
// More options available in specific exporters (URDF, SDF, MuJoCo)
// More options available in processors
}
.. note::
Comments are supported in the ``config.json`` file.
.. note::
Since ``1.0.0``, all configuration entries are now snake case. For backward compatibility reasons, the old
camel case entries are still supported. (for example, ``document_id`` and ``documentId`` are equivalent).
``url`` *(required)*
~~~~~~~~~~~~~~~~~~~~
The Onshape URL of the assembly to be exported. Be sure you are on the correct tab when copying the URL.
``output_format`` *(required)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**required**
This should be either ``urdf`` or ``mujoco`` to specify which output format is wanted for robot description
created by the export.
``output_filename`` *(default: robot)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the name of the output file without extension. By default "robot" (for example: ``robot.urdf``, ``robot.sdf`` or ``robot.xml``).
``assets_directory`` *(default: "assets")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the directory where the assets (like meshes) will be stored.
``assembly_name`` *(optional)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This can be used to specify the name of the assembly (in the Onshape document) to be used for robot export.
If this is not provided, ``onshape-to-robot`` will list the assemblies. If more than one assembly is found,
an error will be raised.
``document_id`` *(optional)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you don't specify the URL, this is the onshape ID of the document to be imported. It can be found in the Onshape URL,
just after ``document/``.
.. code-block:: bash
https://cad.onshape.com/documents/XXXXXXXXX/w/YYYYYYYY/e/ZZZZZZZZ
^^^^^^^^^
This is the document id
``version_id`` *(optional)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you don't specify the URL, this argument can be used to use a specific version of the document instead of the last one. The version ID
can be found in URL, after the ``/v/`` part when selecting a specific version in the tree.
If it is not specified, the workspace will be retrieved and the live version will be used.
``workspace_id`` *(optional)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you don't specify the URL, this argument can be used to use a specific workspace of the document. This can be used for specific branches
ofr your robot without making a version.
The workspace ID can be found in URL, after the ``/w/`` part when selecting a specific version in the tree.
``element_id`` *(optional)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you don't specify the URL, this argument can be used to use a specific element of the document.
The element ID can be found in URL, after the ``/e/`` part when selecting a specific version in the tree.
``configuration`` *(default: "default")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the robot configuration string that will be passed to Onshape. Lists, booleans and quantities are allowed. For example:
.. image:: _static/img/configuration.png
:width: 300px
:align: center
Should be written as the following:
.. code-block:: text
Configuration=Long;RemovePart=true;Length=30mm
.. note::
Alternatively, you can specify the configuration as a dictionary:
.. code-block:: json
{
// ...
"configuration": {
"Configuration": "Long",
"RemovePart": true,
"Length": "30mm"
}
}
``robot_name`` *(default: "dirname")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Specifies the robot name. This value is typically present in the header of the exported files.
If it is not specified, the directory name will be used.
``ignore_limits`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, the joint limits coming from Onshape will be ignored during export.
``ignore`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~
This can be a list of parts that you want to be ignored during the export.
Alternatively, you can use a dict, where the values are either ``all``, ``visual`` or ``collision``. The rules will apply in order of appearance.
You can use wildcards ``*`` to match multiple parts.
You can prefix the part name with ``!`` to exclude it from the rule. For example, the following will ignore all parts for visual, except the ``leg`` part, turning the ignore list to a whitelist:
.. code-block:: json
{
// Ignore everything from visual
"*": "collision",
// Except the leg part
"!leg": "collision"
}
.. note::
The dynamics of the part will not be ignored, but the visual and collision aspect will.
.. _draw-frames:
``draw_frames`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When , the part that is used for positionning the frame is
by default excluded from the output description (a dummy link is kept instead). Passing this option to ``true`` will
keep it instead.
``no_dynamics`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This flag can be set if there is no dynamics. In that case all masses and inertia will be set to 0.
In pyBullet, this will result in static object (think of some environment for example).
``color`` *(default: None)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Can override the color for parts (should be an array: ``[r, g, b]`` with numbers from 0 to 1)
``include_configuration_suffix`` *(default: true)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When this flag is set to ``true`` (default), configurations will be added as a suffix to the part names and STL files.
``post_import_commands`` *(default: [])*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is an array of commands that will be executed after the import is done. It can be used to be sure that
some processing scripts are run everytime you run onshape-to-robot.
``processors`` *(default: None)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See :ref:`custom processors <custom_processors>` for more information.
``round_decimals`` *(default: 12)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Numbers displayed in export will be rounded up using `round()` method. The number of decimals that are kept can be controlled using this parameters.
+56
View File
@@ -0,0 +1,56 @@
.. _custom_processors:
Writing & registering custom Processor
======================================
Introduction
------------
In this documentation, you can find the description of all processors that are `registered by default <https://github.com/Rhoban/onshape-to-robot/blob/master/onshape_to_robot/processors.py>`_. You can also write your own processor, by writing a class and registering it in the ``config.json`` file as described below.
Minimal processor example
-------------------------
Below is a minimal example of processor you can write:
.. code-block:: python
# my_project/my_custom_processor.py
from onshape_to_robot.processor import Processor
from onshape_to_robot.config import Config
from onshape_to_robot.robot import Robot
class MyCustomProcessor(Processor):
def __init__(self, config: Config):
super().__init__(config)
self.use_my_custom: bool = config.get("use_my_custom", False)
def process(self, robot: Robot):
if self.use_my_custom:
print(f"Custom processing for {robot.name} with custom processor.")
Remember that processors processes the robot intermediate representation, that you can find in `robot.py <https://github.com/Rhoban/onshape-to-robot/blob/master/onshape_to_robot/robot.py>`_.
Registering your processor(s)
-----------------------------
To register your processor, use the ``processors`` entry in ``config.json``:
.. code-block:: javascript
{
"processors": [
// Custom processor
"my_project.my_custom_processor:MyCustomProcessor",
// Default processors
"ProcessorScad",
"ProcessorMergeParts",
"ProcessorNoCollisionMeshes"
]
}
.. note::
The list of existing default processors can be found in `processors.py <https://github.com/Rhoban/onshape-to-robot/blob/master/onshape_to_robot/processors.py>`_.
+120
View File
@@ -0,0 +1,120 @@
Design-time considerations
==========================
Workflow overview
-----------------
In order to make your robot possible to export, you need to follow some conventions. The summary is as follows:
* ``onshape-to-robot`` exports an **assembly** of the robot,
* Be sure this assembly is a **top-level assembly**, where instances are robot links (they can be parts or sub-assemblies),
* The **first instance** in the assembly list will be considered as the base link,
* All the instances in the assembly will become links in the export
* **Mate connectors** should have special names (see below for details):
* ``dof_name``: for degrees of freedom
* ``frame_name``: to create a frame (site in MuJoCo)
* ``fix_name``: fix two links together, causing ``onshape-to-robot`` to merge them
* ``closing_name``: to close a kinematic loop (see :ref:`kinematic-loops`)
* Other mates are not considered by ``onshape-to-robot``
* Orphaned links (that are not part of the kinematic chain) will be **fixed to the base link**, with a warning
.. image:: _static/img/design.png
:align: center
Specifying degrees of freedom
-----------------------------
To create a degree of freedom, you should use the ``dof_`` prefix when placing a mate connector.
* If the mate connector is **cylindrical** or **revolute**, a ``revolute`` joint will be issued
* If the mate connector is a **slider**, a ``prismatic`` joint will be issued
* If the mate connector is **fastened**, a ``fixed`` joint will be issued
.. note::
You can specify joint limits in Onshape, they will be understood and exported
Inverting axis orientation
--------------------------
You sometime might want your robot joint to rotate in the opposite direction than the one in the Onshape assembly.
To that end, use the ``inv`` suffix in the mate connector name. For instance, ``dof_head_pitch_inv`` will result in a joint named ``head_pitch`` having the axis inverted with the one from the Onshape assembly.
Naming links
------------
If you create a mate connector and name it ``link_something``, the link corresponding to the instance
on which it is attached will be named ``something`` in the resulting export.
.. _custom-frames:
Adding custom frames in your model
----------------------------------
You can add your own custom frames (such as the end effector or the tip of a leg) to your model.
* In URDF, it will produce a *dummy link* connected to the parent link with a fixed joint
* In SDF, a ``frame`` element will be added
* In MuJoCo, it will result in a *site*
To do so, either:
* Add a mate connector where you want your frame to be, and name it ``frame_something``, where ``something`` is the name of your frame
**OR**
* Add any relation between a body representing your frame and the body you want to attach it to. Name this relation ``frame_something``.
.. image:: _static/img/frames.png
:align: center
:class: padding
Here is a document that can be used (be sure to turn on "composite parts" when inserting it, use the ``frame`` composite part): `Onshape frame part <https://cad.onshape.com/documents/7adc786257f47ce24706bb32/w/774dd3de6bd5bfd65fb4462b/e/c60f72b9088ac4e5058b8904?renderMode=0&uiState=67b64076077d3a02bf5e1c0f>`_
.. note::
The instance used for frame representation is only here for visualization purpose and is excluded from the robot.
You can however include it by setting :ref:`draw_frames <draw-frames>` to ``true`` in the :doc:`config <config>` file, mostly for debugging purposes.
Joint frames
------------
Joint frames are the ones you see in Onshape when you click on the joint in the tree on the left.
Thus, they are always revolving around the z axis, or translating along the *z axis*.
.. image:: _static/img/zaxis.png
:align: center
.. _fixed-robot:
Fixed robot
-----------
If you want to export a robot that is fixed to the ground, use the "Fixed" feture of Onshape:
.. image:: _static/img/fixed.png
:align: center
:class: padding
Robot with multiple base links
------------------------------
The robot can have multiple links. In that case, the first instance appearing on the list will be considered as a separate base link.
.. note::
MuJoCo and SDF both supports multiple base links, while URDF doesn't.
In that case, you might consider using multiple URDF files, or :ref:`adding a dummy base link<processor_dummy_base_link>`. However, this will fix all the base links to the base link without freedom.
Gear relations
--------------
Gear relations are exported by onshape-to-robot. Be sure to click the **source joint** first, and then the **target joint**. They will be exported as ``<mimic>`` in :doc:`URDF <exporter_urdf>` and :doc:`SDF <exporter_sdf>` formats, and as equality constraints in :doc:`MuJoCo <exporter_mujoco>`.
.. image:: _static/img/gear.png
:align: center
+144
View File
@@ -0,0 +1,144 @@
.. _exporter-mujoco:
MuJoCo
======
Introduction
-------------
MuJoCo is a standard physics simulator, coming with an extensive description format.
* Frames will be added as ``site`` tags in the MuJoCo XML file.
* *Actuators* will be created for all actuated joints (see below).
* When :ref:`kinematic loops <kinematic-loops>` are present, they will be enforced using equality constraints.
* If the loop is achieved using a ``fixed`` connector, a ``weld`` constraint will be added.
* If a ``ball`` joint is used, a ``connect`` constraint will be added
* If a ``revolute`` joint is used, two ``connect`` constraints will be used
* Additionally to the ``robot.xml`` file, a ``scene.xml`` file will be produced, adding floor and lighting useful for testing purpose.
``config.json`` entries (MuJoCo)
--------------------------------
Here is an example of complete ``config.json`` file, with details below:
.. code-block:: javascript
{
"url": "document-url",
"output_format": "mujoco",
// ...
// General import options (see config.json documentation)
// ...
// Additional XML file to be included in the URDF (default: "")
"additional_xml": "my_custom_file.xml",
// Override joint properties (default: {})
"joint_properties": {
// Default properties for all joints
"*": {
"actuated": true,
"forcerange": 10.0,
"frictionloss": 0.5,
"limits": [0.5, 1.2]
// ...
},
// Set the properties for a specific joint
"joint_name": {
"forcerange": 20.0,
"frictionloss": 0.1
// ...
}
},
// Override geometry properties (default: {})
"geom_properties": {
// Set properties for specific links using pattern matching
"foot": {
"collision": {
"name": "left_foot_collision",
"friction": "1.2 0.005 0.0001"
}
},
// Wildcard patterns are supported
"leg_*": {
"collision": {
"solimp": "0.9 0.95 0.001",
"solref": "0.02 1"
},
"visual": {
"rgba": "1 0 0 1"
}
}
},
// Override equality attributes
"equalities": {
"closing_branch*": {
"solref": "0.002 1",
"solimp": "0.99 0.999 0.0005 0.5 2"
}
}
}
``joint_properties`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allow to specify the properties of the joints produced in the URDF output. The key should be joint names. The special ``default`` key will set default values for each joints.
Possible values are:
* ``actuated``: *(default: true)* whether an actuator should be associated to this joint,
* ``class``: a ``class="..."`` to be added to the joint (and actuator)
* ``type`` *(default: position)* defines the actuator that will be produced
* ``range`` *(default: true)*: if ``true``, the joint limits are reflected on the joint ``range`` attribute
* ``limits``: Override the joint limits, should be a list of two values (min, max)
* The following are reflected as ``<joint ...>`` attributes:
* ``frictionloss``
* ``damping``
* ``armature``
* ``stiffness``
* The following are reflected as actuator (``<position ...>`` or other) attributes:
* ``kp``, ``kv`` and ``dampratio`` gains
* ``forcerange``
``geom_properties`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allow to specify the properties of the geometries (collision and visual) produced in the MuJoCo output. The key should be part names with support for wildcard pattern matching.
Properties can be specified separately for ``visual`` and ``collision`` geometries, or applied to both if not nested.
Wildcard patterns (``*``, ``?``, ``[seq]``) are supported for matching part names. When multiple patterns match, properties are merged in order with later matches overriding earlier ones.
All properties are added as XML attributes to the ``<geom ...>`` tag. Common MuJoCo geom attributes include:
* ``name``: Override the geometry name
* ``friction``: Friction coefficients (e.g., ``"1.2 0.005 0.0001"``)
* ``solimp``: Solver impedance parameters (e.g., ``"0.9 0.95 0.001"``)
* ``solref``: Solver reference parameters (e.g., ``"0.02 1"``)
* ``contype``: Contact type bitmask (e.g., ``"1"``)
* ``conaffinity``: Contact affinity bitmask (e.g., ``"1"``)
* ``rgba``: Color and transparency (e.g., ``"1 0 0 1"``)
``equalities`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This entry allows to override the equality attributes of the MuJoCo XML file. The key should be the equality name (which might contains wildcards ``*``), and the value should be a dictionary of attributes.
This can be used to adjust the ``solref`` and ``solimp`` attributes of the equality constraints.
``additional_xml`` *(default: "")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you want to include additional XML in the URDF, you can specify the path to the file here. This file will be included in the produced XML.
.. note::
Alternatively, ``additional_xml`` can be a list of files
+107
View File
@@ -0,0 +1,107 @@
SDF
===
Introduction
-------------
The `SDF format <http://sdformat.org/>`_ is an extension of URDF extensively used in ROS.
* When using SDF, frames will be exported as ``<frame>`` items.
* The links and joints always using ``relative_to`` attribute to specify the parent frame, keeping the same coordinates system as in URDF.
* Additionally to the ``robot.sdf`` file, a ``model.config`` file will be produced, adding metadata useful for Gazebo.
``config.json`` entries (SDF)
-----------------------------
Here is an example of complete ``config.json`` file, with details below:
.. code-block:: javascript
{
"url": "document-url",
"output_format": "sdf",
// ...
// General import options (see config.json documentation)
// ...
// Additional XML file to be included in the URDF (default: "")
"additional_xml": "my_custom_file.xml",
// Override joint properties (default: {})
"joint_properties": {
// Default properties for all joints
"*": {
"max_effort": 10.0,
"max_velocity": 6.0,
"friction": 0.5
},
// Set the properties for a specific joint
"joint_name": {
"max_effort": 20.0,
"max_velocity": 10.0,
"friction": 0.1,
"limits": [0.5, 1.2]
},
"wheel": {
"type": "continuous"
}
},
// Override geometry properties (default: {})
"geom_properties": {
// Set properties for specific links using pattern matching
"tibia": {
"collision": {
"mu": "1.2",
"mu2": "0.8"
}
},
// Wildcard patterns are supported
"leg_*": {
"collision": {
"bounce": "0.5",
"max_contacts": "10"
}
}
},
}
``joint_properties`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allow to specify the properties of the joints produced in the URDF output. The key should be joint names. The special ``default`` key will set default values for each joints.
Possible values are:
* ``max_effort``: The maximum effort that can be applied to the joint (added in the ``<joint effort=...>`` tag)
* ``max_velocity``: The maximum velocity of the joint (added in the ``<joint velocity=...>`` tag)
* ``friction``: The friction of the joint (added in the ``<joint_properties friction=...>`` tag)
* ``type``: Sets the joint type (changing the ``<joint type="...">`` tag)
* ``limits``: Override the joint limits, should be a list of two values (min, max)
``geom_properties`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allow to specify the properties of the geometries (collision and visual) produced in the SDF output. The key should be part names with support for wildcard pattern matching.
Properties can be specified separately for ``visual`` and ``collision`` geometries, or applied to both if not nested.
Wildcard patterns (``*``, ``?``, ``[seq]``) are supported for matching part names. When multiple patterns match, properties are merged in order with later matches overriding earlier ones.
All properties are added as nested XML elements within the ``<visual>`` or ``<collision>`` tags. Common SDF geometry properties include:
* ``mu``, ``mu2``: Friction coefficients for collision geometries
* ``bounce``: Restitution coefficient for collision geometries
* ``max_contacts``: Maximum number of contact points for collision geometries
* ``kp``, ``kd``: Contact stiffness and damping parameters
``additional_xml`` *(default: "")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you want to include additional XML in the URDF, you can specify the path to the file here. This file will be included in the produced SDF file.
.. note::
Alternatively, ``additional_xml`` can be a list of files
+119
View File
@@ -0,0 +1,119 @@
URDF
====
Introduction
-------------
URDF is a very standard format that can be exported by ``onshape-to-robot``. Below are the specific configuration entries that can be specified when using this format.
When using this exporter, frames will be added as a *dummy links* attached to their body using a fixed joint
``config.json`` entries (URDF)
------------------------------
Here is an example of complete ``config.json`` file, with details below:
.. code-block:: javascript
{
"url": "document-url",
"output_format": "urdf",
// ...
// General import options (see config.json documentation)
// ...
// Package name (for ROS) (default: "")
"package_name": "my_robot",
// Additional XML file to be included in the URDF (default: "")
"additional_xml": "my_custom_file.xml",
// Exclude inertial data for fixed bodies (default: false)
"set_zero_mass_to_fixed": true,
// Override joint properties (default: {})
"joint_properties": {
// Default properties for all joints
"*": {
"max_effort": 10.0,
"max_velocity": 6.0,
"friction": 0.5
},
// Set the properties for a specific joint
"joint_name": {
"max_effort": 20.0,
"max_velocity": 10.0,
"friction": 0.1,
"limits": [0.5, 1.2]
},
"wheel": {
"type": "continuous"
}
},
// Override geometry properties (default: {})
"geom_properties": {
// Set properties for specific links using pattern matching
"tibia": {
"collision": {
"mu1": "1.2",
"mu2": "0.8"
}
},
// Wildcard patterns are supported
"leg_*": {
"visual": {
"material": "leg_material"
}
}
},
}
``joint_properties`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allow to specify the properties of the joints produced in the URDF output. The key should be joint names. The special ``default`` key will set default values for each joints.
Possible values are:
* ``max_effort``: The maximum effort that can be applied to the joint (added in the ``<joint effort=...>`` tag)
* ``max_velocity``: The maximum velocity of the joint (added in the ``<joint velocity=...>`` tag)
* ``friction``: The friction of the joint (added in the ``<joint_properties friction=...>`` tag)
* ``type``: Sets the joint type (changing the ``<joint type="...">`` tag)
* ``limits``: Override the joint limits, should be a list of two values (min, max)
``geom_properties`` *(default: {})*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allow to specify the properties of the geometries (collision and visual) produced in the URDF output. The key should be part names with support for wildcard pattern matching.
Properties can be specified separately for ``visual`` and ``collision`` geometries, or applied to both if not nested.
Wildcard patterns (``*``, ``?``, ``[seq]``) are supported for matching part names. When multiple patterns match, properties are merged in order with later matches overriding earlier ones.
All properties are added as nested XML elements within the ``<visual>`` or ``<collision>`` tags. Common URDF geometry properties include:
* ``mu1``, ``mu2``: Friction coefficients for collision geometries
* ``kp``, ``kd``: Contact stiffness and damping parameters
* ``material``: Material reference for visual geometries
``package_name`` *(default: "")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you are exporting a URDF for ROS, you can specify the package name here. This will be used in the ``<robot>`` tag.
``additional_xml`` *(default: "")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you want to include additional XML in the URDF, you can specify the path to the file here. This file will be included in the produced URDF file.
.. note::
Alternatively, ``additional_xml`` can be a list of files
``set_zero_mass_to_fixed`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This option sets the mass to 0 for bodies that are :ref:`fixed <fixed-robot>` to the world.
.. note::
In PyBullet, such bodies are indeed recognized as fixed
+116
View File
@@ -0,0 +1,116 @@
Getting started
===============
Installing the package
----------------------
Run the following to install onshape-to-robot from `pypi <https://pypi.org/project/onshape-to-robot/>`_:
.. code-block:: bash
pip install onshape-to-robot
.. _api-key:
Setting up your Authentication
------------------------------
Developer Keys
^^^^^^^^^^^^^^
You will need to obtain API key and secret from the
`My Account > Developer menu <https://cad.onshape.com/user/developer/apiKeys>`_
API key must be set as environment variables.
Using `.bashrc`
~~~~~~~~~~~~~~~
You can add something like this in your ``.bashrc``:
.. code-block:: bash
# .bashrc
# Obtained at https://dev-portal.onshape.com/keys
export ONSHAPE_API=https://cad.onshape.com
export ONSHAPE_ACCESS_KEY=Your_Access_Key
export ONSHAPE_SECRET_KEY=Your_Secret_Key
Using `.env` file
~~~~~~~~~~~~~~~~~
Alternatively, you can also create a ``.env`` file in the root of your project:
.. code-block:: bash
# .env
# Obtained at https://dev-portal.onshape.com/keys
ONSHAPE_API=https://cad.onshape.com
ONSHAPE_ACCESS_KEY=Your_Access_Key
ONSHAPE_SECRET_KEY=Your_Secret_Key
OAuth2
^^^^^^
Onshape alternatively supports `OAuth2 authentication <https://onshape-public.github.io/docs/auth/oauth/>`_. To authenticate this app with an OAuth token, you
can instead set the following in `.barshrc` or `.env`:
.. code-block:: bash
ONSHAPE_API=https://cad.onshape.com
ONSHAPE_SECRET_BEARER=Your_Access_Key
Setting up your export
----------------------
To export your own robot, first create a directory:
.. code-block:: bash
mkdir my-robot
Then edit ``my-robot/config.json``, here is the minimum example:
.. code-block:: json
{
// Onshape URL of the assembly
"url": "https://cad.onshape.com/documents/11a7f59e37f711d732274fca/w/7807518dc67487ad405722c8/e/5233c6445c575366a6cc0d50",
// Output format
"output_format": "urdf"
}
.. note::
The Onshape URL should be the one of your assembly. Be sure to be on the right tab when you copy it.
Once this is done, run the following command:
.. code-block:: bash
onshape-to-robot my-robot
Testing your export
-------------------
You can test your export by running (PyBullet):
.. code-block:: bash
onshape-to-robot-bullet my-robot
Or (MuJoCo):
.. code-block:: bash
onshape-to-robot-mujoco my-robot
What's next ?
-------------
Before you can actually enjoy your export, you need to pay attention to the following:
* ``onshape-to-robot`` comes with some conventions to follow, in order to understand what in your robot is a degree of freedom, a link, a frame, etc. Make sure to read the :doc:`design-time considerations <design>`.
* There are some options you might want to specify in the :doc:`config.json <config>` file.
* Have a look at the `examples <https://github.com/rhoban/onshape-to-robot-examples>`_ available on GitHub.
+40
View File
@@ -0,0 +1,40 @@
Onshape-to-robot documentation
==============================
.. raw:: html
<center>
<video width="70%" controls autoplay muted loop>
<source src="https://github.com/Rhoban/onshape-to-robot-examples/raw/refs/heads/master/videos/sigmaban.mp4" type="video/mp4">
</video>
</center>
<br/>
What is this ?
~~~~~~~~~~~~~~
.. image:: _static/img/main.png
``onshape-to-robot`` is a tool that allows you to export robots designed from the **Onshape CAD** software
to descriptions format like **URDF**, **SDF** or **MuJoCo**, so that you can use them for physics simulation or in your running code
(requesting frames, computing dynamics etc.)
* `onshape-to-robot GitHub repository <https://github.com/rhoban/onshape-to-robot/>`_
* `Robots examples GitHub repository <https://github.com/rhoban/onshape-to-robot-examples/>`_
* `onshape-to-robot on pypi <https://pypi.org/project/onshape-to-robot/>`_
* `video tutorial <https://www.youtube.com/watch?v=C8oK4uUmbRw>`_ (some information may be outdated)
.. toctree::
:maxdepth: 2
:caption: Contents:
getting_started
design
config
exporter_urdf
exporter_sdf
exporter_mujoco
kinematic_loops
processors
cache
+87
View File
@@ -0,0 +1,87 @@
.. _kinematic-loops:
Handling kinematic loops
========================
Some robots have *kinematic loops*, meaning that the kinematic chain is not a tree but a graph.
Introduction
------------
Here is a 2D planar robot with kinematic loop, we assume the two first joints to be actuated and the others to
be passive:
.. raw:: html
<center>
<video width="70%" controls>
<source src="https://github.com/Rhoban/placo-examples/raw/master/kinematics/videos/planar_2dof_trajectory.mp4" type="video/mp4">
</video>
</center>
<br/>
However, robot description are usually **trees**. To model this type of robot, we break it down to a tree. We attach **frames** to this tree, and need to enforce **run-time constraints**.
.. image:: _static/img/opened_chain.png
:width: 300px
:align: center
Specifying closing constraints
------------------------------
While you could manually add :ref:`frames <custom-frames>`, ``onshape-to-robot`` provides a more convenient way to handle kinematic loops: **mate connectors**.
To achieve that, add a **mate** with the name ``closing_something``:
.. image:: _static/img/loop.png
:align: center
:class: padding
Support for ``<equality>`` in MuJoCo
------------------------------------
When using the :ref:`MuJoCo <exporter-mujoco>` format, ``onshape-to-robot`` will add ``<equality>`` constraints to enforce the kinematic loop.
For example, the above robot can be exported using the following ``config.json``:
.. code-block:: javascript
{
// Document URL, MuJoCo output
"url": "https://cad.onshape.com/documents/04b05c47de7576f35c0e99b3/w/68041f3f5c827a258b40039c/e/db543f501b01adf8144064e3",
"output_format": "mujoco",
// Disable the freejoint to fix the robot
"freejoint": false,
// Don't create actuators for passive joints
"joint_properties": {
"passive1": {"actuated": false},
"passive2": {"actuated": false}
}
}
Here is the result of the export:
.. raw:: html
<center>
<video width="70%" controls>
<source src="https://github.com/Rhoban/onshape-to-robot-examples/raw/refs/heads/master/videos/planar_2dof_mujoco.mp4" type="video/mp4">
</video>
</center>
<br/>
Ressources
----------
Here are some ressources on how to handle kinematic loops in software:
* `Onshape assembly <https://cad.onshape.com/documents/04b05c47de7576f35c0e99b3/w/68041f3f5c827a258b40039c/e/db543f501b01adf8144064e3?renderMode=0&uiState=665d8e3a6de6705d2f788204>`_ for the above example robot.
* MuJoCo `equality <https://mujoco.readthedocs.io/en/stable/computation/index.html#coequality>`_ constraints.
* In `pyBullet <https://pybullet.org/wordpress/>`_, you can use `createConstraint` method to add the relevant constraint.
* In the `PlaCo <https://placo.readthedocs.io/>`_ solver, you can create a `RelativePositionTask`. See the `kinematics loop documentation section <https://placo.readthedocs.io/en/latest/kinematics/loop_closures.html>`_ for more details. Some examples created with onshape-to-robot can be found in the `example gallery <https://placo.readthedocs.io/en/latest/kinematics/examples_gallery.html>`_.
+43
View File
@@ -0,0 +1,43 @@
Ball to Euler
=============
Introduction
------------
This processor turns the ``ball`` joints to three revolute joints. This can be convenient if your downstream simulator or tool can't handle ``ball`` joints.
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Convert balls to Euler (default: false)
"ball_to_euler": true,
// Euler angles order (default: "xyz")
"ball_to_euler_order": "xyz",
}
``ball_to_euler`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, all ball joints will be converted to Euler.
If you don't want to convert all your ball joints, you can specify a list of joints as follows:
.. code-block:: javascript
{
// Using specific joint lists, with wildcards
"ball_to_euler": ["joint1", "shoulder_*"],
}
``ball_to_euler_order`` *(default: "xyz")*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set, the order of the euler angles will be set to the given value. The default is ``xyz``.
The order should be ``xyz``, ``xzy``, ``zyx``, ``zxy``, ``yxz`` or ``yzx``.
@@ -0,0 +1,32 @@
Use collisions as visual
========================
Introduction
------------
If this processor is enabled, the items from collision will be also used as visual items.
This can be used for:
* Debugging purpose, when you have no convenient way to visualize collisions in your downstream tools
* Creating a model that is lighter to load
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Removes collision meshes
"collisions_as_visual": true
}
``collisions_as_visual`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, collision will be used as visual.
@@ -0,0 +1,34 @@
Convex decomposition (CoACD)
============================
Introduction
------------
If this processor is enabled, the collision meshes will be decomposed using `CoACD <https://github.com/SarahWeiii/CoACD>`_ convex decomposition.
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Enables convex decomposition
"convex_decomposition": true
// Use Rainbow colors instead of the part color
"rainbow_colors": true
}
``convex_decomposition`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, collision meshes will be decomposed using CoACD.
``rainbow_colors`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, the collision meshes will be colored using rainbow colors instead of the part color.
+28
View File
@@ -0,0 +1,28 @@
.. _processor_dummy_base_link:
Adding dummy base link
======================
Introduction
------------
If this processor is enabled, a dummy base called ``base_link`` will be added in your robot. The base will be attached to this link using a ``fixed`` joint.
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Add a dummy base link (default: false)
"add_dummy_base_link": true
}
``add_dummy_base_link`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, a dummy base link will be added to the robot.
+32
View File
@@ -0,0 +1,32 @@
Using fixed links
=================
Introduction
------------
If this processor is enabled, all parts will be separated in a link, associated with its parent using a ``fixed`` link.
.. note::
Doing this is likely to result in poor performance in physics engine, but can be useful for debugging.
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Adding fixed links, resulting in one link per part
"use_fixed_links": true
}
``use_fixed_links`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, a dummy base link will be added to the robot.
Alternatively, ``use_fixed_links`` can be a list of the links for which you want the fixed links to be added.
+30
View File
@@ -0,0 +1,30 @@
.. _processor-merge-parts:
Merge STLs
==========
Introduction
------------
This processor merge the meshes of all parts in the links into a single one.
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Merge STL meshes (default: false)
"merge_stls": true
}
``merge_stls`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, each link parts meshes will be merged in a single one. The resulting part will be named after the link.
You can also set it to ``"visual"`` to merge only the visual parts, or to ``"collision"`` to merge only the collision parts.
@@ -0,0 +1,41 @@
Removing collision meshes
=========================
Introduction
------------
This processor ensure no collision meshes are rendered.
.. note::
Alternatively, you can use ignore lists to ignore meshes from being processed:
.. code-block:: json
{
"ignore": {
"*": "collision"
}
}
However, this will prevent the meshes from being available to other processors (for example, to be approximated with pure shapes).
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Removes collision meshes
"no_collision_meshes": true
}
``no_collision_meshes`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, collision meshes will be removed.
+69
View File
@@ -0,0 +1,69 @@
OpenSCAD pure shapes approximation
==================================
Introduction
------------
This processor provides you a way to manually approximate your robot into pure shapes.
You can follow the following `video tutorial <https://www.youtube.com/watch?v=C8oK4uUmbRw>`_. Some of the steps are outdated, but the general idea is still the same.
Requirements
------------
For this processor to work, you need to install the OpenSCAD package:
.. code-block:: bash
sudo apt-get install openscad
Process
-------
When the OpenSCAD processor is enabled (see below), it will check for the presence of ``.scad`` files in the output directory. If some are present, they will be parsed and pure shapes will be exported.
.. note::
By default, exporters will use pure shapes for collisions instead of meshes.
You can use the following convenient command to run OpenSCAD on a specific ``.stl`` you want to approximate:
.. code-block:: bash
onshape-to-robot-edit-shape <path_to_stl>
This will open a window similar to the following:
.. image:: _static/img/pure-shape.png
:align: center
:width: 400px
Editing the ``.scad`` file with the same name as the ``.stl`` file. Pure shapes present here will be used as approximation.
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Simplify STL meshes (default: false)
"use_scads": true,
// Can be used to enlarge/shrink the pure shapes (default: 0.0)
"pure_shape_dilatation": 0.0
}
``use_scads`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, the processor will use OpenSCAD pure shapes approximation (see above)
``pure_shape_dilatation`` *(default: 0.0)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A float that can be used to enlarge or shrink the pure shapes. This can be useful to avoid collisions between parts.
Use a negative value to shrink the shapes.
+45
View File
@@ -0,0 +1,45 @@
Simplify STLs
=============
Introduction
------------
This processor will simplify the STLs files so that their size don't exceed a predefined limit.
Used with :ref:`processor-merge-parts`, it will simplify the merged STLs.
Requirements
------------
For this processor to work, ensure pymeshlab is installed:
.. code-block:: bash
pip install pymeshlab
``config.json`` entries
-----------------------
.. code-block:: javascript
{
// ...
// General import options (see config.json documentation)
// ...
// Simplify STL meshes (default: false)
"simplify_stls": true,
// Maximum size of the STL files in MB (default: 3)
"max_stl_size": 1
}
``simplify_stls`` *(default: false)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to ``true``, the STL files will be simplified.
``max_stl_size`` *(default: 3)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The maximum size of the STL files in MB. If the size of a file exceeds this limit, it will be simplified.
You can also set it to ``"visual"`` to simplify only the visual parts, or to ``"collision"`` to simplify only the collision parts.
+44
View File
@@ -0,0 +1,44 @@
Processors
==========
Introduction
~~~~~~~~~~~~
Here is an overview of ``onshape-to-robot`` pipeline:
.. image:: _static/img/architecture.png
* **(1)**: The assembly is retrieved from Onshape, to produce an intermediate representation of the robot. See the `robot.py <https://github.com/Rhoban/onshape-to-robot/blob/master/onshape_to_robot/robot.py>`_ from the source code.
* **(2)**: Some operations can be applied on this representation, those are the **processors**, some of them are listed below.
* **(3)**: The robot is exported to the desired format (URDF, MuJoCo, etc.) using an **exporter**.
.. note::
If you want to tweak your robot in the process, do not hesitate to have a look at the `export.py <https://github.com/Rhoban/onshape-to-robot/blob/master/onshape_to_robot/export.py>`_ script, which is the entry point of the ``onshape-to-robot`` command, and summarize the above-listed steps.
Retrieve and Convert Modes
~~~~~~~~~~~~~~~~~~~~~~~~~~
It is possible to only execute the retrieval step **(1)**, by passing the ``--retrieve`` argument to the ``onshape-to-robot`` command. This will save the intermediate representation of the robot to a file named ``robot.pkl`` in the output directory.
Similarly, steps **(2)** and **(3)** can be executed by passing the ``--convert`` argument, which will load the robot from the ``robot.pkl`` file. Processors will then be executed and the exported will produce the final output. This can be convenient to avoid sending API requests to Onshape while tweaking processors or exporters.
You can also use the ``--save-pickle`` argument to save the robot data after retrieval while still proceeding to conversion.
Processors list
~~~~~~~~~~~~~~~
.. toctree::
:maxdepth: 2
:caption: Processors:
processor_ball_to_euler
processor_merge_parts
processor_simplify_stls
processor_scad
processor_dummy_base_link
processor_no_collision_meshes
processor_collision_as_visual
processor_convex_decomposition
processor_fixed_links
custom_processors