Metadata-Version: 2.4
Name: swift-sim
Version: 2.0.0
Summary: A Python/Javascript Robot Simulator and Visualiser
Author-email: Jesse Haviland <j.haviland@qut.edu.au>, Peter Corke <rvc@petercorke.com>
License: MIT License
        
        Copyright (c) 2020 jhavl
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: homepage, https://github.com/jhavl/swift
Project-URL: documentation, https://jhavl.github.io/swift/
Project-URL: repository, https://github.com/jhavl/swift
Keywords: python,robotics,robotics-toolbox,kinematics,dynamics,motion-planning,trajectory-generation,jacobian,hessian,control,simulation,robot-manipulator,mobile-robot
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=2.0
Requires-Dist: spatialgeometry>=1.4.0
Requires-Dist: websockets
Provides-Extra: dev
Requires-Dist: black; extra == "dev"
Requires-Dist: roboticstoolbox-python~=1.0.0; extra == "dev"
Requires-Dist: swift-sim; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: pyyaml; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx_rtd_theme; extra == "docs"
Requires-Dist: sphinx-autorun; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
Requires-Dist: sphinx-copybutton; extra == "docs"
Provides-Extra: nb
Requires-Dist: ipython; extra == "nb"
Requires-Dist: notebook; extra == "nb"
Dynamic: license-file

# Swift

### Status & Project Health
[![Build Status](https://github.com/jhavl/swift/actions/workflows/python-tests.yml/badge.svg)](https://github.com/jhavl/swift/actions/workflows/python-tests.yml)
[![PyPI version](https://badge.fury.io/py/swift-sim.svg)](https://badge.fury.io/py/swift-sim)
[![Downloads](https://static.pepy.tech/badge/swift-sim/month)](https://pepy.tech/projects/swift-sim)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/swift-sim)](https://img.shields.io/pypi/pyversions/swift-sim)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

### Ecosystem & Dependencies
[![A Python Robotics Package](https://raw.githubusercontent.com/petercorke/robotics-toolbox-python/master/.github/svg/py_collection.min.svg)](https://github.com/petercorke/robotics-toolbox-python)
[![QUT Centre for Robotics Open Source](https://github.com/qcr/qcr.github.io/raw/master/misc/badge.svg)](https://qcr.github.io)

[![powered by three.js](https://img.shields.io/badge/powered_by-three.js-000000?logo=threedotjs&logoColor=white)](https://threejs.org)

[GitHub repository](https://github.com/jhavl/swift) &nbsp;|&nbsp; [Documentation](https://jhavl.github.io/swift/)

Swift is a light-weight browser-based animation visualizer which provides:

  * visualisation of mesh objects (Collada, STL, OBJ, glTF/GLB, PLY, VRML/WRL, and PCD files) and primitive shapes such as cuboids, spheres, cylinders, ellipsoids, polylines and axes;
  * visualisation of multi-link robots created with the [Robotics Toolbox for Python](https://github.com/petercorke/robotics-toolbox-python);
  * interactive UI controls (sliders, buttons, and more) for driving a scene from the browser;
  * recording and saving a video of the simulation;
  * source code which can be read for learning and teaching;

Built using Python and JavaScript (ES modules), Swift is cross-platform (Linux, MacOS, and Windows) while also leveraging the ubiquity and support of these languages.

<p align="center">
 <img src=".github/figures/panda_follow_target.gif" alt="A Panda arm following a slider-controlled target box in Swift">
</p>

Swift provides robotics-specific functionality for rapid prototyping of algorithms, research, and education. 
Through the [Robotics Toolbox for Python](https://github.com/petercorke/robotics-toolbox-python), Swift can visualise over 150 supplied robot models: well-known contemporary robots from Franka-Emika, Kinova, Universal Robotics, Rethink as well as classical robots such as the Puma 560 and the Stanford arm. Swift is under development and will support mobile robots in the future.

## What's new in 2.0

Swift's browser frontend has been rebuilt from scratch as modern, dependency-free ES modules (no bundler, no framework, current three.js) — see [CHANGELOG.md](./CHANGELOG.md) for the full list. For existing users:

  * a bottom-left playback panel with a pause/play button and a realtime-speed selector (Max/1x/0.5x/0.25x) — see [Playback controls](https://jhavl.github.io/swift/swift.html#playback-controls);
  * WebRTC support has been removed (`comms="rtc"`, the `vision` install extra) — it had no live-camera use case and wasn't providing anything a plain WebSocket doesn't already handle for the normal desktop/browser setup this simulator targets;
  * `env.add()` is now four explicit methods — `add_shape()`, `add_ui()`, `add_assembly()`, `add_robot()` — one entry point per kind of thing, no type-checking required. `env.add()` still works and dispatches to these, kept for backward compatibility;
  * `add_robot()`/`add_assembly()` return an **`AssemblyHandle`** that owns that instance's live joint state (`handle.q`, `handle.qd`) — the `robot` model (or bare forward-kinematics function, for `add_assembly()`) stays plain and shareable, driven functionally (`panda.fkine(handle.q)`, `panda.jacobe(handle.q)`). Setting `robot.q`/`robot.qd` directly still works but is deprecated;
  * any shape, assembly, or robot can take a **per-step callback** — `callback=lambda t, values: ...` — invoked by `env.step()` with the current sim time and any named UI element values, returning the new pose (shape) or `q` (assembly/robot). Removes the need to hand-write a loop body that mutates pose/`q` each step;
  * UI elements take an optional `name=`, and their current value is kept in `env.values` — available to any callback as `values[name]` without writing a per-element setter function;
  * `env.show()` prints the current display list (every shape/assembly/robot/UI element, with its id and name if given) for debugging.

## Examples

These build up from the simplest possible scene to a fully interactive one. All are in [`examples/`](./examples) and runnable as-is.
More detailed documentation at [Introduction and tutorial](https://jhavl.github.io/swift/intro.html).

### Render a box, with sliders to move it

Named sliders (`name=...`) push their current value into `env.values`; a per-step callback reads it from there and returns the box's new pose — no per-slider setter function, no manual pose assignment in the loop. The Z slider controls height above the floor (the box's bottom face, not its centre), so it's never possible to clip the box through the ground:

```python
import spatialgeometry as sg
from spatialmath import SE3
from swift import Swift, Slider

env = Swift()
env.launch(realtime=True)

SIDE = 0.2
box = sg.Cuboid([SIDE, SIDE, SIDE], pose=SE3(0, 0, SIDE / 2), color=[0.2, 0.4, 1.0, 1.0])


def box_pose(t, values):
    # z is height above the floor, not the box centre
    return SE3(values["x"], values["y"], values["z"] + SIDE / 2)


env.add_shape(box, callback=box_pose)

env.add_ui(Slider(min=-0.5, max=0.5, step=0.01, value=0.0, label="Box X", unit="m"), name="x")
env.add_ui(Slider(min=-0.5, max=0.5, step=0.01, value=0.0, label="Box Y", unit="m"), name="y")
env.add_ui(Slider(min=0.0, max=0.6, step=0.01, value=0.0, label="Box Z", unit="m"), name="z")

env.run(dt=0.05)  # run forever at 20 fps
```

### Panda arm follows a target, positioned by sliders

The most complete example: a target box is positioned by three named sliders, and on every step the arm runs resolved-rate motion control (`rtb.p_servo`) towards wherever that box currently is — move a slider, the box moves, and the arm continuously chases it. Both the box's pose and the arm's `q` are computed by per-step callbacks reading from `env.values`, so the whole thing runs off a plain `env.step()` loop with no pose/`q` mutation inside it:

```python
import numpy as np
import roboticstoolbox as rtb
import spatialgeometry as sg
import spatialmath as sm
from swift import Swift, Slider

env = Swift()
env.launch(realtime=True)
dt = 0.05

panda = rtb.models.Panda()
handle = env.add_robot(panda)
handle.q = panda.qr

SIDE = 0.05
X0, Y0, Z0 = 0.5, 0.0, 0.3  # initial target position; z is height above the floor

# The gripper points straight down at the target
target_orientation = sm.SE3.Rx(np.pi)

target = sg.Cuboid(
    [SIDE, SIDE, SIDE],
    pose=sm.SE3(X0, Y0, Z0 + SIDE / 2) * target_orientation,
    color=[0.2, 0.4, 1.0, 1.0],
)


def target_pose(t, values):
    return sm.SE3(values["x"], values["y"], values["z"] + SIDE / 2) * target_orientation


env.add_shape(target, callback=target_pose)


def track_target(t, values):
    v, _ = rtb.p_servo(panda.fkine(handle.q), target.T, gain=1.0, threshold=0.01)
    qd = np.linalg.pinv(panda.jacobe(handle.q)) @ v
    return handle.q + qd * dt


handle.callback = track_target

env.add_ui(Slider(min=0.2, max=0.7, step=0.01, value=X0, label="Target X", unit="m"), name="x")
env.add_ui(Slider(min=-0.4, max=0.4, step=0.01, value=Y0, label="Target Y", unit="m"), name="y")
env.add_ui(Slider(min=0.05, max=0.6, step=0.01, value=Z0, label="Target Z", unit="m"), name="z")

env.run(dt=dt)  # run forever, calling track_target/target_pose each step
```

### Embed within a Jupyter Notebook

To embed within a Jupyter Notebook cell, use the `browser="notebook"` option when launching the simulator — any of the examples above work the same way, just swap the `env.launch(...)` line:

```python
env.launch(realtime=True, browser="notebook")
```

## Installing
### Using pip

Swift is designed to be controlled through the [Robotics Toolbox for Python](https://github.com/petercorke/robotics-toolbox-python). By installing the toolbox through PyPI, swift is installed as a dependency

```shell script
pip install roboticstoolbox-python
```

Otherwise, Swift can be installed by

```shell script
pip install swift-sim
```

To include support for embedding within a Jupyter Notebook:

```shell script
pip install swift-sim[nb]
```

Swift requires Python 3.10 or later.

### From GitHub

To install the latest version from GitHub

```shell script
git clone https://github.com/jhavl/swift.git
cd swift
pip install -e .
```
