From e57cb6eebb717e81538421ed9c385ff6d034811b Mon Sep 17 00:00:00 2001 From: JessamyT Date: Fri, 27 Dec 2024 15:33:40 -0800 Subject: [PATCH 01/10] Add services heading, add concepts to start a new machine --- docs/operate/get-started/setup.md | 30 ++++++++++++++++++- .../operate/get-started/supported-hardware.md | 19 ++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/operate/get-started/setup.md b/docs/operate/get-started/setup.md index 20474eb13a..45bb99ede6 100644 --- a/docs/operate/get-started/setup.md +++ b/docs/operate/get-started/setup.md @@ -8,11 +8,39 @@ no_list: true description: "Install the software that drives hardware and connects your device to the cloud." --- +Get started by installing the open-source software that drives your hardware and connects your device to the cloud. +The easiest way to do this is through the Viam app, so that your machines are automatically connected to configuration and remote operation tools. + ## Quickstart 1. Create a [Viam app](https://app.viam.com) account. The Viam app is the online hub for configuring and managing devices as well as viewing data. 1. Add a new _{{< glossary_tooltip term_id="machine" text="machine" >}}_ in the app. A machine represents your device. -1. From the machine page, follow the setup instructions to install `viam-server` on your device and connect it to the cloud. +1. From your machine's page in the Viam app, follow the setup instructions to install `viam-server` on your device and connect it to the cloud. `viam-server` is the executable binary that runs on your device and manages hardware drivers, software, and data capture and sync. +1. Use the **+** button on your machine's **CONFIGURE** tab to add [supported hardware components](/operate/get-started/supported-hardware/) so that `viam-server` can control your specific hardware. +1. Use this same **+** button to configure software services such as [data capture and sync](/data-ai/capture-data/capture-sync/). + +As soon as you configure each component and save the configuration, you can use the **TEST** panel of the component's config card to, for example, view your camera's stream or turn your motor. + +## Concepts + +### What is a machine? + +A _machine_ is a computer (often a single-board computer like a Raspberry Pi or Jetson) or microcontroller and all the hardware attached to it, as well as the software running on it. +You can think of one machine as representing one device, or one robot. + +When you create a new machine in the Viam app, Viam generates a unique set of credentials for that machine that connect the physical machine to its instance in the Viam app. + +### How the configuration works + +The machine setup steps displayed in the Viam app copy your machine's credentials to your machine. +When you turn on your machine, `viam-server` starts up and uses the provided credentials to fetch its configuration from the Viam app. +Once the machine has a configuration, it caches it locally and can use the config for up to 60 days. +Since the configuration is cached locally, your machine does not need to stay connected to the Viam app after it has obtained its configuration file. + +If it is online, the machine checks for new configurations every 15 seconds and changes its config automatically when a new config is available. +All communication happens securely over HTTPS using secret tokens that are in the machine's config. + +If your machine will never connect to the internet, you can also create a [local configuration file](/operate/reference/local-configuration-file/) on the machine itself. diff --git a/docs/operate/get-started/supported-hardware.md b/docs/operate/get-started/supported-hardware.md index 934094e115..f05fd4924a 100644 --- a/docs/operate/get-started/supported-hardware.md +++ b/docs/operate/get-started/supported-hardware.md @@ -85,6 +85,25 @@ After installing `viam-server` or `viam-micro-server` on your computer or microc For details on configuring versioning and environment variables for modules, see [Modular Resource and Module Configuration Details](/operate/reference/module-configuration/). +## Add software services to your machine + +In addition to hardware driver _{{< glossary_tooltip term_id="component" text="components" >}}_ and abstracted "virtual hardware" components, Viam offers _{{< glossary_tooltip term_id="service" text="services" >}}_ to provide higher-level software capabilities. +You can read more about the Viam-maintained services and how to configure them in their respective documentation: + +- [Data capture and sync](/data-ai/capture-data/capture-sync/) +- [ML model deployment](/data-ai/ai/deploy/) +- [Computer vision](/data-ai/ai/run-inference/) +- Motion planning for various components: + - [Robot arm motion](/operate/mobility/move-arm/) + - [Mobile robot navigation](/operate/mobility/move-base/) + +To add a service to your machine: + +1. Click the **+** button on your machine's **CONFIGURE** tab. +1. Click **Service**, then select from available services. + The dropdown list includes services from the Viam Registry as well as the built-in services. +1. Add required attributes according to the README or other documentation. + ## How modules run Modules run alongside [`viam-server`](/architecture/viam-server/) as separate processes, communicating with `viam-server` over UNIX sockets. From 34f64b5a443a8113fd6a165c2d56bbdc10807bcf Mon Sep 17 00:00:00 2001 From: JessamyT Date: Fri, 27 Dec 2024 17:34:47 -0800 Subject: [PATCH 02/10] frame system etc --- docs/dev/reference/apis/services/motion.md | 2 +- docs/operate/_index.md | 5 +- .../{mobile-app/_index.md => mobile-app.md} | 4 +- docs/operate/mobility/define-geometry.md | 176 ++++++++++++++++++ docs/operate/mobility/move-arm.md | 7 + docs/operate/mobility/move-gantry.md | 2 +- .../control}/drive-rover.md | 0 7 files changed, 191 insertions(+), 5 deletions(-) rename docs/operate/control/{mobile-app/_index.md => mobile-app.md} (92%) rename docs/{operate/control/mobile-app => tutorials/control}/drive-rover.md (100%) diff --git a/docs/dev/reference/apis/services/motion.md b/docs/dev/reference/apis/services/motion.md index ecb4f178bd..3f80671f62 100644 --- a/docs/dev/reference/apis/services/motion.md +++ b/docs/dev/reference/apis/services/motion.md @@ -3,7 +3,7 @@ title: "Motion Service API" linkTitle: "Motion" weight: 40 type: "docs" -description: "Give commands to move a machine based on a SLAM map or GPS coordinates or to move a machine's components form one location to another." +description: "Give commands to move a machine based on a SLAM map or GPS coordinates or to move a machine's components from one location to another." icon: true images: ["/icons/components/arm.svg"] date: "2022-01-01" diff --git a/docs/operate/_index.md b/docs/operate/_index.md index f7a9ab6666..94e56ef268 100644 --- a/docs/operate/_index.md +++ b/docs/operate/_index.md @@ -41,7 +41,10 @@ overview: true {{< cards >}} {{% card link="/operate/mobility/define-geometry/" noimage="true" %}} {{% card link="/operate/mobility/define-obstacles/" noimage="true" %}} -{{% card link="/operate/mobility/define-dynamic-obstacles/" noimage="true" %}} + + + {{% card link="/operate/mobility/move-base/" noimage="true" %}} {{% card link="/operate/mobility/move-arm/" noimage="true" %}} {{% card link="/operate/mobility/move-gantry/" noimage="true" %}} diff --git a/docs/operate/control/mobile-app/_index.md b/docs/operate/control/mobile-app.md similarity index 92% rename from docs/operate/control/mobile-app/_index.md rename to docs/operate/control/mobile-app.md index b9e9a7daf8..ab5a618155 100644 --- a/docs/operate/control/mobile-app/_index.md +++ b/docs/operate/control/mobile-app.md @@ -38,7 +38,7 @@ Refer to the [Viam Flutter SDK](https://flutter.viam.dev/) documentation for ava ### Example usage -The following code, part of [Drive a rover in a square in 2 minutes](/how-tos/drive-rover/), shows how you could move a robotic rover base in a square using the base API's [`moveStraight`](https://flutter.viam.dev/viam_sdk/Base/moveStraight.html) and [`spin`](https://flutter.viam.dev/viam_sdk/Base/spin.html) methods: +The following code, part of [Drive a rover in a square in 2 minutes](/tutorials/control/drive-rover/), shows how you could move a robotic rover base in a square using the base API's [`moveStraight`](https://flutter.viam.dev/viam_sdk/Base/moveStraight.html) and [`spin`](https://flutter.viam.dev/viam_sdk/Base/spin.html) methods: ```dart {class="line-numbers linkable-line-numbers"} import 'package:flutter/material.dart'; @@ -78,7 +78,7 @@ class BaseScreen extends StatelessWidget { See the guide for full code and instructions to get started by building a simple app to control a rented Viam rover: {{< cards >}} -{{% card link="/operate/control/mobile-app/drive-rover/" %}} +{{% card link="/tutorials/control/mobile-app/drive-rover/" %}} {{< /cards >}} For a more in-depth guide with more screens, see the following guide: diff --git a/docs/operate/mobility/define-geometry.md b/docs/operate/mobility/define-geometry.md index 72eb770f58..af3243e455 100644 --- a/docs/operate/mobility/define-geometry.md +++ b/docs/operate/mobility/define-geometry.md @@ -7,3 +7,179 @@ type: "docs" no_list: true description: "Specify your robot's dimensions and how it is positioned in space." --- + +Before you can use the motion planning or navigation services, you need to create a description of your machine's dimensions and how it is positioned relative to its surroundings. +The position and orientation readings returned by a component such as an accelerometer or a robot arm have no meaning without a reference frame. + +Use Viam's frame system to define a coordinate system for your machine, and configure the geometries of your machine's components. +You can also [define static obstacles](/operate/mobility/define-obstacles/) for your machine to avoid. + +{{% alert title="Note" color="note" %}} +For complex kinematic chain configuration, useful when creating a module to support an unsupported arm model, see [Configure Complex Kinematic Chains](/operate/reference/kinematic-chain-config/). +{{% /alert %}} + +{{}} + +## Configure a reference frame + +Imagine you have a robotic [arm](/components/arm/) attached to a table. + +Consider one corner of the table the arm is attached to be the origin of the `world`, `(0, 0, 0)`. +Measure from that point to the base of the arm to get the `translation` coordinates. + +- Suppose the arm is offset from the corner by 0.1 m in the positive X direction, and 0.25 m in the negative Y direction. +- Supply this `translation` when configuring the arm component's `frame` information. +- Leave `parent` and `orientation` at their default values. + +{{< tabs name="Example Frame Configuration of Component attached to Static Surface" >}} +{{% tab name="Frame Editor" %}} + +To configure your machine following this example: + +- Navigate to the **CONFIGURE** tab of your machine's page in the [Viam app](https://app.viam.com). +- Select **Builder** mode and [configure your arm](/components/arm/#configuration). +- Select the **Frame** mode. +- From the left-hand menu, select your arm: + {{}} +- Keep the **Parent** frame as `world` and fill in the coordinates for **Translation** (meters) and **Orientation** (degrees) according to the position and orientation of the arm in relation to the `world` frame's origin: + {{}} + +{{< /tab >}} +{{% tab name="JSON Example" %}} + +```json {class="line-numbers linkable-line-numbers"} +{ + "components": [ + { + "depends_on": [], + "name": "myArm", + "model": "ur5e", + "type": "arm", + "namespace": "rdk", + "attributes": { + "host": "127.0.0.1" + }, + "frame": { + "parent": "world", + "translation": { + "x": 100, + "y": -250, + "z": 0 + }, + "orientation": { + "type": "ov_degrees", + "value": { + "x": 0, + "y": 0, + "z": 1, + "th": 0 + } + } + } + } + ] +} +``` + +{{% /tab %}} +{{< /tabs >}} + + +| Parameter | Required? | Required | +| --------- | ----------- | ----- | +| `parent` | **Required** | Default: `world`. The name of the reference frame you want to act as the parent of this frame. | +| `translation` | **Required** | Default: `(0, 0, 0)`. The coordinates that the origin of this component's reference frame has within its parent reference frame.
Units: m in Frame Editor, mm in JSON. | +| `orientation` | **Required** | Default: `(0, 0, 1), 0`. The [orientation vector](/internals/orientation-vector/) that yields the axes of the component's reference frame when applied as a rotation to the axes of the parent reference frame.
**Types**: **Orientation Vector Degrees** (`ov_degrees`), **Orientation Vector Radians** (`ov_radians`), **Euler Angles** (`euler_angles`), and **Quaternion** (`quaternion`). | +| `geometry` | Optional | Default: `none`. Collision geometries for defining bounds in the environment of the machine.
Units: m in Frame Editor, mm in JSON.
**Types**: **Sphere** (`sphere`), **Box** (`box`), and **Capsule** (`capsule`). | + +### Configure nested reference frames + +Imagine you have a robotic arm attached to the actuator (moving part) of a [gantry](/components/gantry/). + +Using a nested reference frame allows you to define the reference frame of the arm with respect to the end effector of the gantry. +This allows `viam-server` to correctly calculate the position of the end of the arm, taking into account the combined motion of the gantry and the arm. + +1. Decide that the origin of the gantry and the origin of the `world` frame will be the same point. + Pick a point on the stationary portion of the gantry and define it as `(0,0,0)`. +1. Pick a point on the gantry end effector where the arm is mounted, with the gantry end effector in what you consider to be the home position. + This is the origin `(0,0,0)` of the arm reference frame. +1. Measure between these two points. + For example, if the arm origin is 10 centimeters above the gantry/world origin, the translation is (0.00, 0.00, 0.10). +1. Configure the gantry reference frame and the arm reference frame as per the instructions in the section above, but set the `parent` of the arm as the gantry, and supply the translation you measured. + +{{< tabs >}} +{{% tab name="Frame Editor" %}} + +- Since the gantry and world have the same origin, don't configure a translation between them: + + {{}} + +- Next, select your arm from the left hand menu. +- Select the **Parent** frame as the gantry, and fill in the coordinates for **Translation** (m) of the arm in relation to the gantry's origin: + + {{}} + +{{< /tab >}} +{{% tab name="JSON Example" %}} + +```json {class="line-numbers linkable-line-numbers"} +{ + "components": [ + { + "name": "myGantry", + "model": "single-axis", + "type": "gantry", + "namespace": "rdk", + "attributes": {}, + "depends_on": [], + "frame": { + "parent": "world", + "translation": { + "y": 0, + "z": 0, + "x": 0 + }, + "orientation": { + "type": "ov_degrees", + "value": { + "x": 0, + "y": 0, + "z": 1, + "th": 0 + } + } + } + }, + { + "depends_on": [], + "name": "myArm", + "model": "ur5e", + "type": "arm", + "namespace": "rdk", + "attributes": { + "host": "127.0.0.1" + }, + "frame": { + "parent": "myGantry", + "translation": { + "x": 0, + "y": 0, + "z": 100 + }, + "orientation": { + "type": "ov_degrees", + "value": { + "x": 0, + "y": 0, + "z": 1, + "th": 0 + } + } + } + } + ] +} +``` + +{{% /tab %}} +{{< /tabs >}} diff --git a/docs/operate/mobility/move-arm.md b/docs/operate/mobility/move-arm.md index c574b79b97..04570c97c8 100644 --- a/docs/operate/mobility/move-arm.md +++ b/docs/operate/mobility/move-arm.md @@ -7,3 +7,10 @@ type: "docs" no_list: true description: "Move an arm with joint positions or automated motion planning." --- + +You can move a robotic arm either with the direct joint position commands of the [arm API](/dev/reference/apis/components/arm/), or with automated complex motion planning using the [motion planning service API](/dev/reference/apis/services/motion/). + +{{< cards >}} +{{% card link="/dev/reference/apis/components/arm/" %}} +{{% card link="/dev/reference/apis/services/motion/" %}} +{{< /cards >}} diff --git a/docs/operate/mobility/move-gantry.md b/docs/operate/mobility/move-gantry.md index ec9199efe6..365724169f 100644 --- a/docs/operate/mobility/move-gantry.md +++ b/docs/operate/mobility/move-gantry.md @@ -5,5 +5,5 @@ weight: 60 layout: "docs" type: "docs" no_list: true -description: "TODO" +description: "Move a gantry with linear actuator positions or automated motion planning." --- diff --git a/docs/operate/control/mobile-app/drive-rover.md b/docs/tutorials/control/drive-rover.md similarity index 100% rename from docs/operate/control/mobile-app/drive-rover.md rename to docs/tutorials/control/drive-rover.md From 0a90ad68771eed1f3a6e12c63630c33726e1da16 Mon Sep 17 00:00:00 2001 From: JessamyT Date: Mon, 30 Dec 2024 16:28:23 -0800 Subject: [PATCH 03/10] Module upload edits --- .../get-started/other-hardware/_index.md | 71 ++++++++++++++++++- .../other-hardware/manage-modules.md | 2 +- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index 2c310dff9a..25568dec85 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -100,7 +100,7 @@ Authenticate your CLI session with Viam using one of the following options: | Namespace/Organization ID | In the [Viam app](https://app.viam.com), navigate to your organization settings through the menu in upper right corner of the page. Find the **Public namespace** and copy that string. | | Resource to add to the module (API) | The [component API](/appendix/apis/#component-apis) your module will implement. | | Model name | Name your component model based on what it supports, for example, if it supports a model of ultrasonic sensor called “XYZ Sensor 1234” you could call your model `xyz_1234` or similar. Must be all-lowercase and use only alphanumeric characters (`a-z` and `0-9`), hyphens (`-`), and underscores (`_`). | -| Enable cloud build | You can select `No` if you will always build the module yourself before uploading it. If you select `Yes` and push the generated files (including the .github folder) and create a release of the format `vX.X.X`, the module will build and upload to the Viam registry and be available for all Viam-supported architectures without you needing to build for each architecture. | +| Enable cloud build | If you select `Yes` (recommended) and push the generated files (including the .github folder) and create a release of the format `vX.X.X`, the module will build and upload to the Viam registry and be available for all Viam-supported architectures without you needing to build for each architecture. `Yes` also makes it easier to [upload](#upload-your-module) using PyInstaller by creating a build entrypoint script. You can select `No` if you will always build the module yourself before uploading it. | | Register module | Select `Yes` unless you are creating a local-only module for testing purposes and do not intend to upload it. | {{< /expand >}} @@ -752,7 +752,74 @@ Do not change the module_id.

To package (for Python) and upload your module and make it available to configure on machines in your organization (or in any organization, depending on how you set `visibility` in the meta.json file): {{< tabs >}} -{{% tab name="Python" %}} +{{% tab name="Python: pyinstaller (recommended)" %}} + +The recommended approach for Python is to use [PyInstaller](https://pypi.org/project/pyinstaller/) to compile your module into a packaged executable: a standalone file containing your program, the Python interpreter, and all of its dependencies. +When packaged in this fashion, you can run the resulting executable on your desired target platform or platforms without needing to install additional software or manage dependencies manually. + +{{% alert title="Note" color="note" %}} +To follow these PyInstaller packaging steps, you must have enabled cloud build when moving through the module generator prompts. +If you did not, you will need to manually create a build.sh entrypoint script. +{{% /alert %}} + +To create a packaged executable: + +1. First, activate the [Python virtual environment](/sdks/python/python-venv/) the module generator created for you to ensure your module has access to any required libraries. + Run the following command from inside your module's directory to activate the virtual environment: + + ```sh {id="terminal-prompt" class="command-line" data-prompt="$"} + source venv/bin/activate + ``` + + Be sure you are within your Python virtual environment for the rest of these steps. + Your terminal prompt should include the name of your virtual environment in parentheses. + +1. Edit the requirements.txt file, adding PyInstaller (`pyinstaller`), and the Google API Python client (`google-api-python-client`) to the list of dependencies: + + ```sh { class="command-line" data-prompt="$"} + pyinstaller + google-api-python-client + ``` + +1. Install the dependencies listed in your `requirements.txt` file within your Python virtual environment using the following command: + + ```sh { class="command-line" data-prompt="$"} + python -m pip install -r requirements.txt -U + ``` + +1. Then compile your module, adding the Google API Python client as a hidden import: + + ```sh { class="command-line" data-prompt="$"} + python -m PyInstaller --onefile --hidden-import="googleapiclient" src/main.py + ``` + + If you need to include any additional data files to support your module, specify them using the `--add-data` flag: + + ```sh { class="command-line" data-prompt="$"} + python -m PyInstaller --onefile --hidden-import="googleapiclient" --add-data src/arm/my_arm_kinematics.json:src/arm/ src/main.py + ``` + + By default, the output directory for the packaged executable is dist, and the name of the executable is derived from the name of the input script (in this case, main). + +We recommend you use PyInstaller with the [`build-action` GitHub action](https://github.com/viamrobotics/build-action) which provides a simple cross-platform build setup for multiple platforms: x86 and Arm Linux distributions, and MacOS. +See [Update an existing module using a GitHub action](/how-tos/manage-modules/#update-an-existing-module-using-a-github-action) for more information. + +{{% alert title="Note" color="note" %}} + +PyInstaller does not support relative imports in entrypoints (imports starting with `.`). +If you get `"ImportError: attempted relative import with no known parent package"`, set up a stub entrypoint as described on [GitHub](https://github.com/pyinstaller/pyinstaller/issues/2560). + +In addition, PyInstaller does not support cross-compiling: you must compile your module on the target architecture you wish to support. +For example, you cannot run a module on a Linux `arm64` system if you compiled it using PyInstaller on a Linux `amd64` system. +Viam makes this easy to manage by providing a build system for modules. +Follow [these instructions](/cli/#using-the-build-subcommand) to automatically build for each system your module can support using Viam's [CLI](/cli/). + +{{% /alert %}} + +{{% /tab %}} +{{% tab name="Python: venv" %}} + +You can use the following package and upload method if you opted not to enable cloud build when you ran `viam module generate`. 1. To package the module as an archive, run the following command from inside the module directory: diff --git a/docs/operate/get-started/other-hardware/manage-modules.md b/docs/operate/get-started/other-hardware/manage-modules.md index 8d85bd56d6..79a4b01c05 100644 --- a/docs/operate/get-started/other-hardware/manage-modules.md +++ b/docs/operate/get-started/other-hardware/manage-modules.md @@ -101,7 +101,7 @@ For more information, see the [`viam module` command](/cli/#module). ### Update an existing module using a GitHub action To update an existing module in the [Viam Registry](https://app.viam.com/registry) using continuous integration (CI), you can use one of two GitHub actions. -You can only use these GitHub actions if you have already created the module by running `viam module create` and `viam module update`. +You can only use these GitHub actions if you have already created the module by running `viam module create` and `viam module upload` (or `viam module generate` and opting to register the module, and then `viam module upload`). For most use cases, we recommend the [`build-action` GitHub action](https://github.com/viamrobotics/build-action) which provides a simple cross-platform build setup for multiple platforms: x86, ARM Linux, and MacOS. However, if you already have your own CI with access to arm runners or only intend to build on `x86` or `mac`, you may also use the [`upload-module` GitHub action](https://github.com/viamrobotics/upload-module) instead which allows you to define the exact build steps. From 8a2e840a910a0e413d547428f37ab974092a44ab Mon Sep 17 00:00:00 2001 From: JessamyT Date: Mon, 30 Dec 2024 18:02:36 -0800 Subject: [PATCH 04/10] Base, arm examples and API description fixes --- docs/dev/reference/apis/components/arm.md | 5 +++-- docs/dev/reference/apis/services/motion.md | 4 ++-- docs/operate/control/mobile-app.md | 2 +- docs/operate/mobility/define-obstacles.md | 7 +++++++ docs/operate/mobility/move-arm.md | 14 +++++++++++++- docs/operate/mobility/move-base.md | 21 ++++++++++++++++++++- docs/operate/mobility/move-gantry.md | 10 ++++++++++ 7 files changed, 56 insertions(+), 7 deletions(-) diff --git a/docs/dev/reference/apis/components/arm.md b/docs/dev/reference/apis/components/arm.md index 8448d550ef..13a8adc09a 100644 --- a/docs/dev/reference/apis/components/arm.md +++ b/docs/dev/reference/apis/components/arm.md @@ -3,14 +3,15 @@ title: "Arm API" linkTitle: "Arm" weight: 10 type: "docs" -description: "Give commands to your arm components for linear motion planning, including self-collision prevention and obstacle avoidance." +description: "Give commands to your arm components for linear motion planning." icon: true images: ["/icons/components/arm.svg"] date: "2022-01-01" # updated: "" # When the content was last entirely checked --- -The arm API allows you to give commands to your [arm components](/components/arm/) for linear motion planning, including self-collision prevention and obstacle avoidance. +The arm API allows you to give commands to your [arm components](/components/arm/) for linear motion planning. +If you want self-collision prevention and obstacle avoidance, use the [motion API](/dev/reference/apis/services/motion/). The arm component supports the following methods: diff --git a/docs/dev/reference/apis/services/motion.md b/docs/dev/reference/apis/services/motion.md index 3f80671f62..1ef07bfb5b 100644 --- a/docs/dev/reference/apis/services/motion.md +++ b/docs/dev/reference/apis/services/motion.md @@ -3,14 +3,14 @@ title: "Motion Service API" linkTitle: "Motion" weight: 40 type: "docs" -description: "Give commands to move a machine based on a SLAM map or GPS coordinates or to move a machine's components from one location to another." +description: "Give commands to move a machine's components from one location or pose to another." icon: true images: ["/icons/components/arm.svg"] date: "2022-01-01" # updated: "" # When the content was last entirely checked --- -The motion service API allows you to give commands to your [motion service](/services/motion/) for moving a machine based on a SLAM map or GPS coordinates or for moving a machine's components from one location to another. +The motion service API allows you to give commands to your [motion service](/services/motion/) for moving a mobile robot based on a SLAM map or GPS coordinates or for moving a machine's components from one pose to another. The motion service supports the following methods: diff --git a/docs/operate/control/mobile-app.md b/docs/operate/control/mobile-app.md index ab5a618155..ae8964acfc 100644 --- a/docs/operate/control/mobile-app.md +++ b/docs/operate/control/mobile-app.md @@ -78,7 +78,7 @@ class BaseScreen extends StatelessWidget { See the guide for full code and instructions to get started by building a simple app to control a rented Viam rover: {{< cards >}} -{{% card link="/tutorials/control/mobile-app/drive-rover/" %}} +{{% card link="/tutorials/control/drive-rover/" %}} {{< /cards >}} For a more in-depth guide with more screens, see the following guide: diff --git a/docs/operate/mobility/define-obstacles.md b/docs/operate/mobility/define-obstacles.md index 9d2b2e8cfd..37d81f366d 100644 --- a/docs/operate/mobility/define-obstacles.md +++ b/docs/operate/mobility/define-obstacles.md @@ -7,3 +7,10 @@ type: "docs" no_list: true description: "Spatially describe your robot's working environment for collision avoidance." --- + +## Example usage + +{{< cards >}} +{{% card link="/tutorials/services/constrain-motion/" %}} +{{% card link="/tutorials/projects/claw-game/" %}} +{{< /cards >}} diff --git a/docs/operate/mobility/move-arm.md b/docs/operate/mobility/move-arm.md index 04570c97c8..fa783d7262 100644 --- a/docs/operate/mobility/move-arm.md +++ b/docs/operate/mobility/move-arm.md @@ -8,9 +8,21 @@ no_list: true description: "Move an arm with joint positions or automated motion planning." --- -You can move a robotic arm either with the direct joint position commands of the [arm API](/dev/reference/apis/components/arm/), or with automated complex motion planning using the [motion planning service API](/dev/reference/apis/services/motion/). +You have two options for moving a robotic arm: + +- Use direct joint position commands and simple linear commands with the [arm API](/dev/reference/apis/components/arm/) +- Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/) {{< cards >}} {{% card link="/dev/reference/apis/components/arm/" %}} {{% card link="/dev/reference/apis/services/motion/" %}} {{< /cards >}} + +## Tutorials and example usage + +{{< cards >}} +{{% card link="/how-tos/move-robot-arm/" %}} +{{% card link="/tutorials/services/plan-motion-with-arm-gripper/" %}} +{{% card link="/tutorials/services/constrain-motion/" %}} +{{% card link="/tutorials/projects/claw-game/" %}} +{{< /cards >}} diff --git a/docs/operate/mobility/move-base.md b/docs/operate/mobility/move-base.md index 1bc081df21..37d0b5cf50 100644 --- a/docs/operate/mobility/move-base.md +++ b/docs/operate/mobility/move-base.md @@ -1,9 +1,28 @@ --- linkTitle: "Move a base" -title: "Move a base through space" +title: "Move a wheeled robot base" weight: 40 layout: "docs" type: "docs" no_list: true description: "Move a mobile robot with manual or autonomous navigation." --- + +You have three options for moving a mobile robot base: + +- Give direct commands such as `Spin` and `MoveStraight` using the [base API](/dev/reference/apis/components/base/) +- Send the base to a destination on a SLAM map or to a GPS coordinate using the [motion planning service API's](/dev/reference/apis/services/motion/) `MoveOnMap` or `MoveOnGlobe` commands, respectively +- Define waypoints and move your base along those waypoints while avoiding obstacles, using the [navigation service API](/dev/reference/apis/services/navigation) + +{{< cards >}} +{{% card link="/dev/reference/apis/components/base/" %}} +{{% card link="/dev/reference/apis/services/motion/" %}} +{{% card link="/dev/reference/apis/services/navigation/" %}} +{{< /cards >}} + +## Example usage + +{{< cards >}} +{{% card link="/tutorials/control/drive-rover/" %}} +{{% card link="/tutorials/services/navigate-with-rover-base/" %}} +{{< /cards >}} diff --git a/docs/operate/mobility/move-gantry.md b/docs/operate/mobility/move-gantry.md index 365724169f..508f47021e 100644 --- a/docs/operate/mobility/move-gantry.md +++ b/docs/operate/mobility/move-gantry.md @@ -7,3 +7,13 @@ type: "docs" no_list: true description: "Move a gantry with linear actuator positions or automated motion planning." --- + +You have two options for moving a gantry: + +- Move each axis of the gantry directly with the [gantry API](/dev/reference/apis/components/gantry/) +- Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/) + +{{< cards >}} +{{% card link="/dev/reference/apis/components/gantry/" %}} +{{% card link="/dev/reference/apis/services/motion/" %}} +{{< /cards >}} From b2a7b6b27e4193ae803fd1479b8908b6febb8dbf Mon Sep 17 00:00:00 2001 From: JessamyT Date: Tue, 31 Dec 2024 12:52:42 -0800 Subject: [PATCH 05/10] Put how-to and tutorials into move arm section, fix arm API description --- docs/dev/reference/apis/components/arm.md | 4 +- docs/operate/mobility/move-arm/_index.md | 28 +++ .../mobility/move-arm}/constrain-motion.md | 6 +- .../mobility/move-arm/move-robot-arm.md | 220 ++++++++++++++++++ .../move-arm}/plan-motion-with-arm-gripper.md | 12 +- .../reference/components/arm/_index.md | 2 +- 6 files changed, 262 insertions(+), 10 deletions(-) create mode 100644 docs/operate/mobility/move-arm/_index.md rename docs/{tutorials/services => operate/mobility/move-arm}/constrain-motion.md (99%) create mode 100644 docs/operate/mobility/move-arm/move-robot-arm.md rename docs/{tutorials/services => operate/mobility/move-arm}/plan-motion-with-arm-gripper.md (98%) diff --git a/docs/dev/reference/apis/components/arm.md b/docs/dev/reference/apis/components/arm.md index 13a8adc09a..865d367838 100644 --- a/docs/dev/reference/apis/components/arm.md +++ b/docs/dev/reference/apis/components/arm.md @@ -10,8 +10,8 @@ date: "2022-01-01" # updated: "" # When the content was last entirely checked --- -The arm API allows you to give commands to your [arm components](/components/arm/) for linear motion planning. -If you want self-collision prevention and obstacle avoidance, use the [motion API](/dev/reference/apis/services/motion/). +The arm API allows you to give commands to your [arm components](/components/arm/) for linear motion planning with self-collision prevention. +If you want the arm to avoid obstacles, or you want to plan complex motion in an automated way, use the [motion API](/dev/reference/apis/services/motion/). The arm component supports the following methods: diff --git a/docs/operate/mobility/move-arm/_index.md b/docs/operate/mobility/move-arm/_index.md new file mode 100644 index 0000000000..f2310b53ae --- /dev/null +++ b/docs/operate/mobility/move-arm/_index.md @@ -0,0 +1,28 @@ +--- +linkTitle: "Move an arm" +title: "Move an arm" +weight: 50 +layout: "docs" +type: "docs" +no_list: true +description: "Move an arm with joint positions or automated motion planning." +--- + +You have two options for moving a robotic arm: + +- Use direct joint position commands and simple linear commands with the [arm API](/dev/reference/apis/components/arm/) +- Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/) + +{{< cards >}} +{{% card link="/dev/reference/apis/components/arm/" %}} +{{% card link="/dev/reference/apis/services/motion/" %}} +{{< /cards >}} + +## Tutorials and example usage + +{{< cards >}} +{{% card link="/operate/mobility/move-arm/move-robot-arm/" %}} +{{% card link="/operate/mobility/move-arm/plan-motion-with-arm-gripper/" %}} +{{% card link="/operate/mobility/move-arm/constrain-motion/" %}} +{{% card link="/tutorials/projects/claw-game/" %}} +{{< /cards >}} diff --git a/docs/tutorials/services/constrain-motion.md b/docs/operate/mobility/move-arm/constrain-motion.md similarity index 99% rename from docs/tutorials/services/constrain-motion.md rename to docs/operate/mobility/move-arm/constrain-motion.md index a401f511b7..dc94184bfa 100644 --- a/docs/tutorials/services/constrain-motion.md +++ b/docs/operate/mobility/move-arm/constrain-motion.md @@ -1,6 +1,6 @@ --- -title: "Add Constraints and Transforms to a Motion Plan" -linkTitle: "Add Motion Constraints" +title: "Add constraints and transforms to a motion plan" +linkTitle: "Add motion constraints" type: "docs" description: "Use constraints and transforms with the motion service." videos: @@ -19,6 +19,8 @@ level: "Intermediate" date: "2023-07-03" # updated: "" cost: 8400 +aliases: + - /tutorials/services/constrain-motion/ --- {{}} diff --git a/docs/operate/mobility/move-arm/move-robot-arm.md b/docs/operate/mobility/move-arm/move-robot-arm.md new file mode 100644 index 0000000000..5bc63ec8e5 --- /dev/null +++ b/docs/operate/mobility/move-arm/move-robot-arm.md @@ -0,0 +1,220 @@ +--- +title: "Move a robot arm with the arm API" +linkTitle: "Use the arm API" +weight: 70 +type: "docs" +tags: ["arm", "components"] +images: ["/how-tos/move_to_position.gif"] +videos: ["/how-tos/move_to_position.webm", "/how-tos/move_to_position.mp4"] +description: "Connect to a robotic arm and control it with the arm API." +aliases: + - /tutorials/motion/accessing-and-moving-robot-arm + - /tutorials/motion/ + - /how-tos/move-robot-arm/ +languages: ["Python", "Go"] +viamresources: ["arm"] +platformarea: ["mobility"] +level: "Intermediate" +date: "2024-10-31" +# updated: "" # When the tutorial was last entirely checked +cost: "8400" +--- + +In this guide you'll use Viam's Python or Go SDK to get the current position of your robot arm and issue movement commands. + +{{< alert title="In this page" color="tip" >}} + +1. [Access the arm](#access-the-arm) +1. [Move the arm](#move-the-arm) + +{{< /alert >}} + +## Requirements + +You need the following hardware to complete this tutorial: + +- A single-board computer or other computer to run `viam-server`. +- A Linux, macOS or Windows computer that can run SDK code. +- A [robotic arm](/components/arm/). + +## Access the arm + +{{< table >}} +{{% tablestep link="/configure/" %}} +**1. Configure a machine with an arm** + +{{% snippet "setup.md" %}} + +Add an arm component. +Select a model that supports your arm. Refer to the [documentation for the model](/components/arm/#configuration) for information about your arm's configuration attributes. + +{{}} +Save your config. + +{{% /tablestep %}} +{{% tablestep link="/appendix/apis/components/arm/#getendposition" %}} +**2. Get the position of the end effector** + +One way to describe the state of a robot arm is with the position of the end effector, or the "tool" or "hand" of the arm. +The code to get this information is a part of the autogenerated code sample the Viam app provides for your machine. +Go to the **Code sample** page of the **CONNECT** tab and select either Python or Go. + +{{% snippet "show-secret.md" %}} + +Then, copy and paste the sample code into a file and run the resulting script to see the resources available on your screen and the position of the end effector output as a [`Pose`](/internals/orientation-vector/). +For more information, see [`GetEndPosition`](/appendix/apis/components/arm/#getendposition). + +{{% /tablestep %}} +{{% tablestep %}} +**3. Get the joint positions** + +The state of a robot arm can also be described as the list of positions of each joint attached to the arm. +To get that information, add the following code right after the code that gets the end effector pose from the prior code sample: + +{{< tabs >}} +{{% tab name="Python" %}} + +```python +# Joint Positions of arm1 +my_arm_joint_positions = await arm_1.get_joint_positions() +print(f"myArm get_joint_positions return value: {my_arm_joint_positions}") +``` + +{{% /tab %}} +{{% tab name="Go" %}} + +```go +// Joint Positions of arm1 +myArmJointPositions, err := arm1.JointPositions(context.Background(), nil) +if err != nil { + logger.Error(err) + return +} +logger.Infof("myArm JointPositions return value:", myArmJointPositions) +``` + +{{% /tab %}} +{{< /tabs >}} + +Run your code again. +Each individual value corresponds to the current position of a particular joint on your robot. +You can also see these values reflected on the **CONTROL** tab in the Viam app for your robot arm. + +{{% /tablestep %}} +{{< /table >}} + +## Move the arm + +The two main options for controlling arm movement are through **joint position commands** and through **pose commands**. +Joint position commands allow for more detailed control and flexibility instead of commanding movement with the end effector position in a pose command. + +{{< alert title="Caution" color="caution" >}} +Be careful when instructing robot arms to move. +Before running any code, ensure your robotic arm has enough space and that there are no obstacles. +Also pay attention to your surroundings, double-check your code for correctness, and make sure anyone nearby is aware and alert before issuing commands to your machine. +{{< /alert >}} + +{{< table >}} +{{% tablestep %}} +**1. Initiate motion with a joint position command** + +{{< tabs >}} +{{% tab name="Python" %}} +Add the following line to your import list to be able to assign values to a `JointPositions` data structure: + +```python +from viam.proto.component.arm import JointPositions +``` + +Add the following code to your script: + +```python +# Command a joint position move: move the forearm of the arm slightly up +cmd_joint_positions = JointPositions(values=[0, 0, -30.0, 0, 0, 0]) +await arm_1.move_to_joint_positions(positions=cmd_joint_positions) +``` + +{{% /tab %}} +{{% tab name="Go" link="/appendix/apis/components/arm/#movetojointpositions" %}} +Add `armapi "go.viam.com/api/component/arm/v1"` to your import list. +Add the following code to your script: + +```go +// Command a joint position move: move the forearm of the arm slightly up +cmdJointPositions := &armapi.JointPositions{Values: []float64{0.0, 0.0, -30.0, 0.0, 0.0, 0.0}} +err = arm1.MoveToJointPositions(context.Background(), cmdJointPositions, nil) +if err != nil { + logger.Error(err) + return +} +``` + +{{% /tab %}} +{{< /tabs >}} + +{{}} + +Run the code. +The third joint of your arm should move 30 degrees. +For more information, see [`MoveToJointPositions`](/appendix/apis/components/arm/#movetojointpositions). + +{{% /tablestep %}} +{{% tablestep link="/appendix/apis/components/arm/#movetoposition" %}} +**2. Command to move to position** + +{{< tabs >}} +{{% tab name="Python" %}} + +Add the following code to your script: + +```python +# Generate a simple pose move +100mm in the +Z direction of the arm +cmd_arm_pose = await arm_1.get_end_position() +cmd_arm_pose.z += 100.0 +await arm_1.move_to_position(pose=cmd_arm_pose) +``` + +{{% /tab %}} +{{% tab name="Go" %}} +Add `"go.viam.com/rdk/spatialmath"` to your import list. + +Add the following code to your script: + +```go +// Generate a simple pose move +100mm in the +Z direction of the arm +currentArmPose, err := arm1.EndPosition(context.Background(), nil) +if err != nil { + logger.Error(err) + return +} +adjustedArmPoint := currentArmPose.Point() +adjustedArmPoint.Z += 100.0 +cmdArmPose := spatialmath.NewPose(adjustedArmPoint, currentArmPose.Orientation()) + +err = arm1.MoveToPosition(context.Background(), cmdArmPose, nil) +if err != nil { + logger.Error(err) + return +} +``` + +{{% /tab %}} +{{< /tabs >}} + +{{}} + +This code gets the arm's end position, makes a 100 millimeter adjustment in the +Z direction, and then uses that adjustment as a goal [`Pose`](/internals/orientation-vector/) when commanding arm motion. +Run the code to see your arm move 100 mm upwards. +For more information, see [`MoveToPosition`](/appendix/apis/components/arm/#movetoposition). + +{{% /tablestep %}} +{{< /table >}} + +## Next steps + +{{< cards >}} +{{% card link="/tutorials/services/plan-motion-with-arm-gripper" %}} +{{% card link="/tutorials/projects/claw-game/" %}} +{{< /cards >}} + +For more resources on robot kinematics, read through the Wikipedia pages for [Forward kinematics](https://en.wikipedia.org/wiki/Forward_kinematics) and [Inverse kinematics](https://en.wikipedia.org/wiki/Inverse_kinematics). diff --git a/docs/tutorials/services/plan-motion-with-arm-gripper.md b/docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md similarity index 98% rename from docs/tutorials/services/plan-motion-with-arm-gripper.md rename to docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md index 8d0e77b4c0..73b894849b 100644 --- a/docs/tutorials/services/plan-motion-with-arm-gripper.md +++ b/docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md @@ -1,8 +1,8 @@ --- -title: "Plan Motion with an Arm and a Gripper" -linkTitle: "Plan Motion with an Arm" +title: "Plan motion with an arm and gripper" +linkTitle: "Use the motion service" type: "docs" -description: "Use the motion service to move robot arms and other components." +description: "Use the motion service to move a robot arm and gripper." videos: [ "/tutorials/videos/motion_armmoving.webm", @@ -19,6 +19,8 @@ date: "2023-03-07" # updated: "" cost: 8400 no_list: true +aliases: + - /tutorials/services/plan-motion-with-arm-gripper/ --- With Viam you can move individual components, like [arms](/components/arm/), by issuing commands like `MoveToPosition` or `MoveToJointPosition`. @@ -55,8 +57,8 @@ This also helps simplify and shorten the code examples presented below. ## Configure a robot -The [robot configuration from the prior tutorial](/how-tos/move-robot-arm/) should be used for this tutorial. -We will revisit that robot configuration and add new components during specific sections below. +Use the robot configuration from the [prerequisite guide](/how-tos/move-robot-arm/) for this tutorial as well. +We will revisit that robot configuration and add new components. The motion service is one of the "built-in" services, which means that no initial configuration is required to start planning and executing complex motion. All you need is a robot with a component that can move, such as a robotic arm. diff --git a/docs/operate/reference/components/arm/_index.md b/docs/operate/reference/components/arm/_index.md index 8cf9d59df4..37f79db6fc 100644 --- a/docs/operate/reference/components/arm/_index.md +++ b/docs/operate/reference/components/arm/_index.md @@ -20,7 +20,7 @@ date: "2024-10-21" # SME: Peter L --- -The arm component provides an API for linear motion planning, including self-collision prevention and obstacle avoidance. +The arm component provides an API for linear motion, including self-collision prevention. If you have a physical robotic arm, consisting of a serial chain of joints and links, with a fixed end and an end effector end, use an arm component. From eb993520bc45ef220087350e052bd8bc27aa054f Mon Sep 17 00:00:00 2001 From: JessamyT Date: Tue, 31 Dec 2024 15:15:57 -0800 Subject: [PATCH 06/10] Delete old move an arm page --- docs/operate/mobility/move-arm.md | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 docs/operate/mobility/move-arm.md diff --git a/docs/operate/mobility/move-arm.md b/docs/operate/mobility/move-arm.md deleted file mode 100644 index fa783d7262..0000000000 --- a/docs/operate/mobility/move-arm.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -linkTitle: "Move an arm" -title: "Move an arm" -weight: 50 -layout: "docs" -type: "docs" -no_list: true -description: "Move an arm with joint positions or automated motion planning." ---- - -You have two options for moving a robotic arm: - -- Use direct joint position commands and simple linear commands with the [arm API](/dev/reference/apis/components/arm/) -- Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/) - -{{< cards >}} -{{% card link="/dev/reference/apis/components/arm/" %}} -{{% card link="/dev/reference/apis/services/motion/" %}} -{{< /cards >}} - -## Tutorials and example usage - -{{< cards >}} -{{% card link="/how-tos/move-robot-arm/" %}} -{{% card link="/tutorials/services/plan-motion-with-arm-gripper/" %}} -{{% card link="/tutorials/services/constrain-motion/" %}} -{{% card link="/tutorials/projects/claw-game/" %}} -{{< /cards >}} From e8fdbd60ace40fabbd6185b484fb95a561987e2b Mon Sep 17 00:00:00 2001 From: JessamyT Date: Tue, 31 Dec 2024 16:52:15 -0800 Subject: [PATCH 07/10] Gantry, arm changes, etc --- docs/operate/control/headless-app.md | 20 +-- .../operate/get-started/supported-hardware.md | 1 + docs/operate/mobility/define-obstacles.md | 30 +++- docs/operate/mobility/move-arm/_index.md | 2 +- .../mobility/move-arm/constrain-motion.md | 1 + .../mobility/move-arm/move-robot-arm.md | 2 +- .../move-arm/plan-motion-with-arm-gripper.md | 1 + docs/operate/mobility/move-base.md | 4 +- docs/operate/mobility/move-gantry.md | 165 +++++++++++++++++- docs/operate/mobility/use-input-to-act.md | 2 +- 10 files changed, 210 insertions(+), 18 deletions(-) diff --git a/docs/operate/control/headless-app.md b/docs/operate/control/headless-app.md index 9a060b1bfe..540034cce3 100644 --- a/docs/operate/control/headless-app.md +++ b/docs/operate/control/headless-app.md @@ -25,7 +25,7 @@ You can run your code directly on the machine's single-board computer (SBC), or ### On a separate computer -We recommend running your script on a laptop, desktop, or server if: +We recommend running your code on a laptop, desktop, or server if: - You are using computationally-intensive programs involving, for example, computer vision or motion planning, and - You have a stable internet connection @@ -34,7 +34,7 @@ The client code will establish a connection to the instance of `viam-server` on ### On the machine itself -We recommend running your script on the SBC that directly controls your hardware if: +We recommend running your code on the SBC that directly controls your hardware if: - Your machines have intermittent or no network connectivity, or - You want to reduce latency, for example for running [PID control loops](https://en.wikipedia.org/wiki/Proportional%E2%80%93integral%E2%80%93derivative_controller), or @@ -93,7 +93,7 @@ You can use the toggle to include the machine API key and API key ID, though we If your code will connect to multiple machines or use [Platform APIs](/dev/reference/apis/#platform-apis) you can create an API key with broader access. -## Write your control script +## Write your control code For API reference including code snippets for each method, see [Viam's Client APIs](/dev/reference/apis/). @@ -335,13 +335,13 @@ if __name__ == '__main__': {{< /expand >}} -## Run your script +## Run your code -You can run your script manually from your terminal, or you can automatically run it each time your machine starts. +You can run your code manually from your terminal, or you can automatically run it each time your machine starts. -### Run your script manually +### Run your code manually -To run your script on a laptop or desktop, or to run it on your machine's SBC manually for testing purposes, execute the following command in a terminal: +To run your code on a laptop or desktop, or to run it on your machine's SBC manually for testing purposes, execute the following command in a terminal: {{< tabs >}} {{% tab name="Python" %}} @@ -365,13 +365,13 @@ For information on running C++ code see [the instructions on GitHub](https://git {{% /tab %}} {{< /tabs >}} -### Run your script as an automatic process +### Run your code as an automatic process -If you want your script to run each time your machine boots, configure the script as a _{{< glossary_tooltip term_id="process" text="process" >}}_ on your machine. +If you want your code to run each time your machine boots, configure the code as a _{{< glossary_tooltip term_id="process" text="process" >}}_ on your machine. Configured processes are managed by `viam-server` and are a way to run any specified command either once on boot or continuously over the lifecycle of `viam-server`. {{% alert title="Tip" color="tip" %}} -If you are running your code from a laptop or desktop, we do not recommend configuring your script to run as a process because doing so will cause the process to run whenever you boot your computer, even when you are using your computer for unrelated purposes. +If you are running your code from a laptop or desktop, we do not recommend configuring your code to run as a process because doing so will cause the process to run whenever you boot your computer, even when you are using your computer for unrelated purposes. {{% /alert %}} To configure a process, click the **+** button on your machine's **CONFIGURE** tab and select **Process**. diff --git a/docs/operate/get-started/supported-hardware.md b/docs/operate/get-started/supported-hardware.md index f05fd4924a..cd7860fea1 100644 --- a/docs/operate/get-started/supported-hardware.md +++ b/docs/operate/get-started/supported-hardware.md @@ -96,6 +96,7 @@ You can read more about the Viam-maintained services and how to configure them i - Motion planning for various components: - [Robot arm motion](/operate/mobility/move-arm/) - [Mobile robot navigation](/operate/mobility/move-base/) + - [Gantry motion planning](/operate/mobility/move-gantry/) To add a service to your machine: diff --git a/docs/operate/mobility/define-obstacles.md b/docs/operate/mobility/define-obstacles.md index 37d81f366d..a27a2086fa 100644 --- a/docs/operate/mobility/define-obstacles.md +++ b/docs/operate/mobility/define-obstacles.md @@ -8,9 +8,35 @@ no_list: true description: "Spatially describe your robot's working environment for collision avoidance." --- -## Example usage +To prevent your machine from colliding with objects or surfaces in its environment, you can define obstacles and include them in calls to the [motion service API](/dev/reference/apis/services/motion/). +The motion service will take into account the obstacles as well as the geometry of the machine itself when planning motion. + +Start by [defining your machine's geometry](/operate/mobility/define-geometry/) so that you can define the obstacles with respect to the machine's reference frame. + +Next, define one or more obstacles. +Here is a Python example from the [Add constraints and transforms to a motion plan guide](/operate/mobility/move-arm/constrain-motion/#modify-your-robots-working-environment): + +```python {class="line-numbers linkable-line-numbers"} +box_origin = Pose(x=400, y=0, z=50+z_offset) +box_dims = Vector3(x=120.0, y=80.0, z=100.0) +box_object = Geometry(center=box_origin, + box=RectangularPrism(dims_mm=box_dims)) + +obstacles_in_frame = GeometriesInFrame(reference_frame="world", + geometries=[table_object, box_object]) +``` + +Finally, pass your obstacles to the motion planning API. +See the API documentation for the following methods which can take into account obstacles: + +- [Move](/dev/reference/apis/services/motion/#move) + - Obstacles are passed as part of the `world_state` parameter +- [MoveOnMap](/dev/reference/apis/services/motion/#moveonmap) +- [MoveOnGlobe](/dev/reference/apis/services/motion/#moveonglobe) + +## Tutorials and example usage {{< cards >}} -{{% card link="/tutorials/services/constrain-motion/" %}} +{{% card link="/operate/mobility/move-arm/constrain-motion/" %}} {{% card link="/tutorials/projects/claw-game/" %}} {{< /cards >}} diff --git a/docs/operate/mobility/move-arm/_index.md b/docs/operate/mobility/move-arm/_index.md index f2310b53ae..f6748f30a9 100644 --- a/docs/operate/mobility/move-arm/_index.md +++ b/docs/operate/mobility/move-arm/_index.md @@ -8,7 +8,7 @@ no_list: true description: "Move an arm with joint positions or automated motion planning." --- -You have two options for moving a robotic arm: +You have two options for moving a robotic [arm](/operate/reference/components/arm/): - Use direct joint position commands and simple linear commands with the [arm API](/dev/reference/apis/components/arm/) - Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/) diff --git a/docs/operate/mobility/move-arm/constrain-motion.md b/docs/operate/mobility/move-arm/constrain-motion.md index dc94184bfa..1a753ba60e 100644 --- a/docs/operate/mobility/move-arm/constrain-motion.md +++ b/docs/operate/mobility/move-arm/constrain-motion.md @@ -2,6 +2,7 @@ title: "Add constraints and transforms to a motion plan" linkTitle: "Add motion constraints" type: "docs" +weight: 60 description: "Use constraints and transforms with the motion service." videos: [ diff --git a/docs/operate/mobility/move-arm/move-robot-arm.md b/docs/operate/mobility/move-arm/move-robot-arm.md index 5bc63ec8e5..0bf8b9b848 100644 --- a/docs/operate/mobility/move-arm/move-robot-arm.md +++ b/docs/operate/mobility/move-arm/move-robot-arm.md @@ -1,7 +1,7 @@ --- title: "Move a robot arm with the arm API" linkTitle: "Use the arm API" -weight: 70 +weight: 20 type: "docs" tags: ["arm", "components"] images: ["/how-tos/move_to_position.gif"] diff --git a/docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md b/docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md index 73b894849b..c8451f61b6 100644 --- a/docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md +++ b/docs/operate/mobility/move-arm/plan-motion-with-arm-gripper.md @@ -2,6 +2,7 @@ title: "Plan motion with an arm and gripper" linkTitle: "Use the motion service" type: "docs" +weight: 40 description: "Use the motion service to move a robot arm and gripper." videos: [ diff --git a/docs/operate/mobility/move-base.md b/docs/operate/mobility/move-base.md index 37d0b5cf50..70e0306918 100644 --- a/docs/operate/mobility/move-base.md +++ b/docs/operate/mobility/move-base.md @@ -8,7 +8,7 @@ no_list: true description: "Move a mobile robot with manual or autonomous navigation." --- -You have three options for moving a mobile robot base: +You have three options for moving a mobile robot [base](/operate/reference/components/base/): - Give direct commands such as `Spin` and `MoveStraight` using the [base API](/dev/reference/apis/components/base/) - Send the base to a destination on a SLAM map or to a GPS coordinate using the [motion planning service API's](/dev/reference/apis/services/motion/) `MoveOnMap` or `MoveOnGlobe` commands, respectively @@ -20,7 +20,7 @@ You have three options for moving a mobile robot base: {{% card link="/dev/reference/apis/services/navigation/" %}} {{< /cards >}} -## Example usage +## Tutorials and example usage {{< cards >}} {{% card link="/tutorials/control/drive-rover/" %}} diff --git a/docs/operate/mobility/move-gantry.md b/docs/operate/mobility/move-gantry.md index 508f47021e..d3196ce957 100644 --- a/docs/operate/mobility/move-gantry.md +++ b/docs/operate/mobility/move-gantry.md @@ -8,7 +8,7 @@ no_list: true description: "Move a gantry with linear actuator positions or automated motion planning." --- -You have two options for moving a gantry: +You have two options for moving a [gantry](/operate/reference/components/gantry/): - Move each axis of the gantry directly with the [gantry API](/dev/reference/apis/components/gantry/) - Use automated complex motion planning with the [motion planning service API](/dev/reference/apis/services/motion/) @@ -17,3 +17,166 @@ You have two options for moving a gantry: {{% card link="/dev/reference/apis/components/gantry/" %}} {{% card link="/dev/reference/apis/services/motion/" %}} {{< /cards >}} + +## Usage + +### Prerequisites + +{{% expand "A running machine connected to the Viam app. Click to see instructions." %}} + +{{% snippet "setup.md" %}} + +{{% /expand%}} + +### Steps + +{{< table >}} +{{% tablestep link="/operate/reference/components/motor/" %}} +**1. Configure the gantry's motor components** + +First, connect the gantry's motors to your machine. + +Then, navigate to the **CONFIGURE** tab of your machine's page in the [Viam app](https://app.viam.com). +Click the **+** icon next to your machine part in the left-hand menu and select **Component**. + +Complete the motor configuration and use the **TEST** panel in the configuration card to test that the motor is working. + +Repeat this for each motor of your gantry. + +{{% /tablestep %}} +{{% tablestep link="/operate/reference/components/gantry/" %}} +**2. Configure a gantry component** + +Use the **+** button again to add gantry components. + +If you have a multi-axis gantry, [configure a single-axis gantry](/operate/reference/components/gantry/single-axis/) for each axis, and then [configure a multi-axis gantry](/operate/reference/components/gantry/multi-axis/) to combine them all into one coordinated unit. + +{{% /tablestep %}} +{{% tablestep link="/operate/control/headless-app/" %}} +**3. Connect code to your gantry** + +Go to your machine's **CONNECT** tab in the Viam app. +Select your preferred programming language and copy the code snippet. + +See [Create a web app](/operate/control/web-app/), [Create a mobile app](/operate/control/mobile-app/), or [Create a headless app](/operate/control/headless-app/) for more information, depending on your use case. + +{{% /tablestep %}} +{{% tablestep %}} +**4. Write code to control your gantry** + +{{< expand "Gantry API usage example" >}} + +The following is an example Python script. + +For more methods and code snippets in more languages, see [Gantry API](/dev/reference/apis/components/gantry/). + +```python {class="line-numbers linkable-line-numbers"} +import asyncio + +from viam.robot.client import RobotClient +from viam.rpc.dial import Credentials, DialOptions +from viam.components.gantry import Gantry + +async def connect(): + opts = RobotClient.Options.with_api_key( + # Replace "" (including brackets) with your machine's api key + api_key='', + # Replace "" (including brackets) with your machine's api key id + api_key_id='' + ) + return await RobotClient.at_address('', opts) + +async def main(): + machine = await connect() + + print('Resources:') + print(machine.resource_names) + + # get gantry-1 + gantry_1 = Gantry.from_robot(machine, "gantry-1") + gantry_1_return_value = await gantry_1.get_lengths() + print(f"gantry-1 get_lengths return value: {gantry_1_return_value}") + + # Home the gantry + await gantry_1.home() + + # Move this three-axis gantry to a position 5mm in the positive Y direction from (0,0,0) + # and set the speed of each axis to 8 mm/sec + await gantry_1.move_to_position([0,5,0], [8,8,8]) + + # Don't forget to close the machine when you're done! + await machine.close() + +if __name__ == '__main__': + asyncio.run(main()) + +``` + +{{< /expand >}} + +{{< expand "Motion planning API usage example" >}} + +The following is an example Python script. + +{{% alert title="Important" color="note" %}} + +Before using the motion service with a gantry, you must [define your gantry's reference frame](/operate/mobility/define-geometry/). + +{{% /alert %}} + +For more methods and code snippets in more languages, see [Motion API](/dev/reference/apis/services/motion/). + +```python {class="line-numbers linkable-line-numbers"} +import asyncio + +from viam.robot.client import RobotClient +from viam.rpc.dial import Credentials, DialOptions +from viam.components.gantry import Gantry +from viam.services.motion import MotionClient +from viam.proto.common import Pose, PoseInFrame + +async def connect(): + opts = RobotClient.Options.with_api_key( + # Replace "" (including brackets) with your machine's api key + api_key='', + # Replace "" (including brackets) with your machine's api key id + api_key_id='' + ) + return await RobotClient.at_address('', opts) + +async def main(): + machine = await connect() + + print('Resources:') + print(machine.resource_names) + + # get gantry-1 + gantry_1 = Gantry.from_robot(machine, "gantry-1") + gantry_1_return_value = await gantry_1.get_lengths() + print(f"gantry-1 get_lengths return value: {gantry_1_return_value}") + + motion = MotionClient.from_robot(robot=machine, name="builtin") + + goal_pose = Pose(x=0, y=0, z=300, o_x=0, o_y=0, o_z=1, theta=0) + # Move the gantry + await motion.move(component_name=gantry_1, + destination=PoseInFrame(reference_frame="myFrame", pose=goal_pose)) + + # Don't forget to close the machine when you're done! + await machine.close() + +if __name__ == '__main__': + asyncio.run(main()) + +``` + +{{< /expand >}} + +{{% /tablestep %}} +{{% tablestep link="/operate/reference/components/motor/" %}} +**5. Run your code** + +Make sure your gantry's path is unobstructed, and run your code. + +{{% /tablestep %}} +{{< /table >}} diff --git a/docs/operate/mobility/use-input-to-act.md b/docs/operate/mobility/use-input-to-act.md index 0ff341e45e..bba4e2580c 100644 --- a/docs/operate/mobility/use-input-to-act.md +++ b/docs/operate/mobility/use-input-to-act.md @@ -5,5 +5,5 @@ weight: 70 layout: "docs" type: "docs" no_list: true -description: "TODO" +description: "Actuate your machine based on sensor readings or other inputs." --- From da38ae0a737cb7f4fd0b3801ec4ac5901772a5e6 Mon Sep 17 00:00:00 2001 From: JessamyT Date: Thu, 2 Jan 2025 12:41:48 -0800 Subject: [PATCH 08/10] Use input to act, and fix module typo --- docs/operate/mobility/use-input-to-act.md | 100 ++++++++++++++++++ .../operate/reference/module-configuration.md | 2 +- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/docs/operate/mobility/use-input-to-act.md b/docs/operate/mobility/use-input-to-act.md index bba4e2580c..9da33f2fad 100644 --- a/docs/operate/mobility/use-input-to-act.md +++ b/docs/operate/mobility/use-input-to-act.md @@ -7,3 +7,103 @@ type: "docs" no_list: true description: "Actuate your machine based on sensor readings or other inputs." --- + +You can program your machine to move based on sensor readings or other inputs. + +{{% alert title="Disambiguation" color="tip" %}} +If you want to act or send alerts based on computer vision, see [Act based on inferences](/data-ai/ai/act/) or [Alert on inferences](/data-ai/ai/alert/). +To alert based on data, see [Alert on data](/data-ai/data/advanced/alert-data/). +{{% /alert %}} + +## Prerequisites + +{{% expand "A running machine connected to the Viam app. Click to see instructions." %}} + +{{% snippet "setup.md" %}} + +{{% /expand%}} + +{{% expand "Components configured on your machine." %}} + +[Configure your sensing and actuation hardware](/operate/get-started/supported-hardware/) as components of your machine. + +This may include sensors, cameras, motors, bases, arms, gantries, servos, grippers, or other components. + +{{% /expand%}} + +## Program your machine + +{{< table >}} +{{% tablestep %}} +**1. Start building your app** + +Depending on your use case, see [Create a web app](/operate/control/web-app/), [Create a mobile app](/operate/control/mobile-app/), or [Create a headless app](/operate/contro/headless-app/) for information on installing an SDK and connecting your code to your machine. + +{{% /tablestep %}} +{{% tablestep %}} +**2. Get an input** + +Use one of the input APIs, such as: + +- [Sensor](/dev/reference/apis/components/sensor/) + + - Input methods include `GetReadings`. + Python example: + + ```python {class="line-numbers linkable-line-numbers"} + my_sensor = Sensor.from_robot(robot=machine, name='my_sensor') + + # Get the readings provided by the sensor. + readings = await my_sensor.get_readings() + ``` + +- [Power sensor](/dev/reference/apis/components/power-sensor/) + + - Input methods include `GetVoltage`, `GetCurrent`, `GetPower`, and `GetReadings`. + +- [Board](/dev/reference/apis/components/board/) + - Input methods include `GetGPIO`, `GetPWM`, `PWMFrequency`, `GetDigitalInterruptValue`, and `ReadAnalogReader`. + +If you are using camera input with computer vision, see [Act based on inferences](/data-ai/ai/act/) for relevant examples. + +{{% /tablestep %}} +{{% tablestep %}} +**3. Actuate based on the input** + +To move your actuator, use your actuator component's API, with logic based on your input: + +- [Motor](/dev/reference/apis/components/motor/) + + - Actuation methods include `SetPower`, `SetRPM`, `GoFor`, `GoTo`, `Stop`. + Python example: + + ```python {class="line-numbers linkable-line-numbers"} + my_motor = Motor.from_robot(robot=machine, name="my_motor") + + # Assume your sensor returns a reading with a key called "level" + # If the sensor reads less than 50, spin the motor at 95 RPM. + current_level = readings.get('level') + if (current_level < 50): + await my_motor.set_rpm(rpm=95) + else: + await my_motor.stop() + ``` + +- [Servo](/dev/reference/apis/components/servo/) + - Actuation methods include `Move`. +- [Gripper](/dev/reference/apis/components/gripper/) + - Actuation methods include `Open`, `Grab`, `Stop`. +- [Board](/dev/reference/apis/components/board/) + - Input methods include `SetGPIO`, `SetPWM`, `SetPWMFrequency`, and `WriteAnalog`. + +If your use case involves planning coordinated motion of multiple motors, see [Move a base](/operate/mobility/move-base/), [Move an arm](/operate/mobility/move-arm/), or [Move a gantry](/operate/mobility/move-gantry/) for more information on how to automate intelligent motion planning. +Instead of actuating using the component API, you can use the [motion service API](/dev/reference/apis/services/motion/)'s `Move`, `MoveOnMap`, or `MoveOnGlobe` commands. + +{{% /tablestep %}} +{{% /table %}} + +## Usage examples + +To water a plant based on moisture sensor readings using the board API, see [Plant watering robot with a Raspberry Pi](/tutorials/projects/make-a-plant-watering-robot/). + +To turn a fan on or off based on air quality sensor data, see [Automate air filtration with air quality sensors](https://codelabs.viam.com/guide/air-quality/index.html?index=..%2F..index#0). diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index a5e501825d..c0f1c0d455 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -199,7 +199,7 @@ The following properties are configurable for each module: | `type` | string | **Required** | `registry` or `local`, depending on whether the module is in the [Viam Registry](https://app.viam.com/registry) or is only available [locally](/how-tos/create-module/#test-your-module-locally) on your computer. | | `module_id` | string | **Required** | The module author's organization namespace or UUID, then a colon, then the name of the module. Identical to the first two pieces of the {{< glossary_tooltip term_id="model-namespace-triplet" text="model namespace triplet" >}}. `:`. | | `name` | string | **Required** | A name for this instance of the module. | -| `env` | object | Optional | Environment variables available to the module. For example `{ "API_KEY": "${environment.API_KEY}" }`. Some modules require that you set environment variables as part of configuration. Check the module's readme for more information. See [environments variables](#environment-variables). | +| `env` | object | Optional | Environment variables available to the module. For example `{ "API_KEY": "${environment.API_KEY}" }`. Some modules require that you set environment variables as part of configuration. Check the module's readme for more information. See [environment variables](#environment-variables). | #### Module versioning From f2fa90a936b8d8640197a1e04f294a81574234c0 Mon Sep 17 00:00:00 2001 From: JessamyT Date: Thu, 2 Jan 2025 18:05:10 -0800 Subject: [PATCH 09/10] Fix PyInstaller order of operations, and DOCS-3305 fix local testing steps --- assets/registry/restart-module.png | Bin 0 -> 10295 bytes .../get-started/other-hardware/_index.md | 111 ++++++++++++------ 2 files changed, 73 insertions(+), 38 deletions(-) create mode 100644 assets/registry/restart-module.png diff --git a/assets/registry/restart-module.png b/assets/registry/restart-module.png new file mode 100644 index 0000000000000000000000000000000000000000..d256bb689daa370a54cb96039c3d396b04db3de0 GIT binary patch literal 10295 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.github folder) and create a release of the format `vX.X.X`, the module will build and upload to the Viam registry and be available for all Viam-supported architectures without you needing to build for each architecture. `Yes` also makes it easier to [upload](#upload-your-module) using PyInstaller by creating a build entrypoint script. You can select `No` if you will always build the module yourself before uploading it. | -| Register module | Select `Yes` unless you are creating a local-only module for testing purposes and do not intend to upload it. | +| Register module | Select `Yes` unless you are creating a local-only module for testing purposes and do not intend to upload it. If you decline to register the module at this point, you can run [`viam module create`](/dev/tools/cli/#module) to register it later. | {{< /expand >}} @@ -535,7 +535,24 @@ Make sure to physically connect your sensor to your machine's computer to prepar **1. Prepare to run your module** {{< tabs >}} -{{% tab name="Python" %}} +{{% tab name="Python: pyinstaller (recommended)" %}} +{{% alert title="Note" color="note" %}} +To follow these PyInstaller packaging steps, you must have enabled cloud build when moving through the module generator prompts. +If you did not, you will need to manually create a build.sh entrypoint script. +{{% /alert %}} + +From within the hello-world directory, create a virtual Python environment with the necessary packages and then build an executable by running the setup and build scripts: + +```sh {id="terminal-prompt" class="command-line" data-prompt="$"} +sh setup.sh +sh build.sh +``` + +This environment is where the local module will run. +`viam-server` does not need to run inside this environment. + +{{% /tab %}} +{{% tab name="Python: venv" %}} Create a virtual Python environment with the necessary packages by running the setup file from within the hello-world directory: @@ -566,7 +583,26 @@ make build On your machine's **CONFIGURE** tab in the [Viam app](https://app.viam.com), click the **+** (create) icon in the left-hand menu. Select **Local module**, then **Local module**. -Type in the _absolute_ path on your machine's filesystem to your module's executable file, for example /Users/jessamy/my-python-sensor-module/run.sh or /Users/artoo/my-go-module/main.go. +Type in the _absolute_ path on your machine's filesystem to your module's executable file, for example: + +{{< tabs >}} +{{% tab name="Python: pyinstaller (recommended)" %}} + +Users/jessamy/my-python-sensor-module/dist/main + +{{% /tab %}} +{{% tab name="Python: venv" %}} + +/Users/jessamy/my-python-sensor-module/run.sh + +{{% /tab %}} +{{% tab name="Go" %}} + +/Users/artoo/my-go-module/main.go + +{{% /tab %}} +{{< /tabs >}} + Click **Create**. {{% /tablestep %}} @@ -595,8 +631,25 @@ For example, if you created a sensor component, check whether readings are displ {{}} -If it works, you're almost ready to share your module by uploading it to the registry. +{{% /tablestep %}} +{{% tablestep %}} +**4. Iterate** + +If your component works, you're almost ready to share your module by uploading it to the registry. If not, you have some debugging to do. + +Each time you make changes to your local module, you need to rebuild the module and then restart its instance on your machine. +Run the following command to rebuild it: + +```sh {id="terminal-prompt" class="command-line" data-prompt="$"} +viam module build local +``` + +Then restart it in your machine's **CONFIGURE** tab in the Viam app. +In upper right corner of the module's card, click the three dot (**...**) icon, then click **Restart**. + +{{}} + For help, don't hesitate to reach out on the [Community Discord](https://discord.gg/viam). {{% /tablestep %}} @@ -604,6 +657,8 @@ For help, don't hesitate to reach out on the [Community Discord](https://discord ## Upload your module +Once you are done testing locally, you can upload your module to the [Viam Registry](https://app.viam.com/registry) and make it available either to all machines in your organization, or to the general public. + {{< table >}} {{% tablestep %}} **1. Create a README (optional)** @@ -759,47 +814,27 @@ When packaged in this fashion, you can run the resulting executable on your desi {{% alert title="Note" color="note" %}} To follow these PyInstaller packaging steps, you must have enabled cloud build when moving through the module generator prompts. -If you did not, you will need to manually create a build.sh entrypoint script. {{% /alert %}} -To create a packaged executable: - -1. First, activate the [Python virtual environment](/sdks/python/python-venv/) the module generator created for you to ensure your module has access to any required libraries. - Run the following command from inside your module's directory to activate the virtual environment: - - ```sh {id="terminal-prompt" class="command-line" data-prompt="$"} - source venv/bin/activate - ``` +The build.sh script packaged a tarball for you when you ran it before [testing](#test-your-module-locally). - Be sure you are within your Python virtual environment for the rest of these steps. - Your terminal prompt should include the name of your virtual environment in parentheses. +Run the `viam module upload` CLI command to upload the module to the registry, replacing `any` with one or more of `linux/any` or `darwin/any` if your module requires Linux OS-level support or macOS OS-level support, respectively. +If your module does not require OS-level support (such as platform-specific dependencies), you can run the following command exactly: -1. Edit the requirements.txt file, adding PyInstaller (`pyinstaller`), and the Google API Python client (`google-api-python-client`) to the list of dependencies: - - ```sh { class="command-line" data-prompt="$"} - pyinstaller - google-api-python-client - ``` - -1. Install the dependencies listed in your `requirements.txt` file within your Python virtual environment using the following command: - - ```sh { class="command-line" data-prompt="$"} - python -m pip install -r requirements.txt -U - ``` - -1. Then compile your module, adding the Google API Python client as a hidden import: - - ```sh { class="command-line" data-prompt="$"} - python -m PyInstaller --onefile --hidden-import="googleapiclient" src/main.py - ``` +```sh {id="terminal-prompt" class="command-line" data-prompt="$"} +viam module upload --version 1.0.0 --platform any module.tar.gz +``` - If you need to include any additional data files to support your module, specify them using the `--add-data` flag: +For details on platform support, see [Using the `--platform` argument](/cli/#using-the---platform-argument). - ```sh { class="command-line" data-prompt="$"} - python -m PyInstaller --onefile --hidden-import="googleapiclient" --add-data src/arm/my_arm_kinematics.json:src/arm/ src/main.py - ``` +For details about versioning, see [Module versioning](/operate/get-started/supported-hardware/#module-versioning). - By default, the output directory for the packaged executable is dist, and the name of the executable is derived from the name of the input script (in this case, main). +{{% alert title="Important" color="note" %}} +The `viam module upload` command only supports one `platform` argument at a time. +If you would like to upload your module with support for multiple platforms, you must run a separate `viam module upload` command for each platform. +Use the _same version number_ when running multiple `upload` commands of the same module code if only the `platform` support differs. +The Viam Registry page for your module displays the platforms your module supports for each version you have uploaded. +{{% /alert %}} We recommend you use PyInstaller with the [`build-action` GitHub action](https://github.com/viamrobotics/build-action) which provides a simple cross-platform build setup for multiple platforms: x86 and Arm Linux distributions, and MacOS. See [Update an existing module using a GitHub action](/how-tos/manage-modules/#update-an-existing-module-using-a-github-action) for more information. From 01c15cb9f3e08ad8b2e41371e3f2baeec140a6dd Mon Sep 17 00:00:00 2001 From: JessamyT <75634662+JessamyT@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:09:56 -0800 Subject: [PATCH 10/10] Apply suggestions from code review Co-authored-by: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> --- docs/operate/get-started/supported-hardware.md | 5 +---- docs/operate/mobility/define-geometry.md | 4 ++-- docs/operate/mobility/move-arm/move-robot-arm.md | 9 +-------- docs/operate/mobility/use-input-to-act.md | 2 +- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/docs/operate/get-started/supported-hardware.md b/docs/operate/get-started/supported-hardware.md index cd7860fea1..213ecde594 100644 --- a/docs/operate/get-started/supported-hardware.md +++ b/docs/operate/get-started/supported-hardware.md @@ -93,10 +93,7 @@ You can read more about the Viam-maintained services and how to configure them i - [Data capture and sync](/data-ai/capture-data/capture-sync/) - [ML model deployment](/data-ai/ai/deploy/) - [Computer vision](/data-ai/ai/run-inference/) -- Motion planning for various components: - - [Robot arm motion](/operate/mobility/move-arm/) - - [Mobile robot navigation](/operate/mobility/move-base/) - - [Gantry motion planning](/operate/mobility/move-gantry/) +- Motion planning for [robot arm motion](/operate/mobility/move-arm/), [mobile robot navigation](/operate/mobility/move-base/), and [gantry motion planning](/operate/mobility/move-gantry/) To add a service to your machine: diff --git a/docs/operate/mobility/define-geometry.md b/docs/operate/mobility/define-geometry.md index af3243e455..a3fe30c258 100644 --- a/docs/operate/mobility/define-geometry.md +++ b/docs/operate/mobility/define-geometry.md @@ -8,7 +8,7 @@ no_list: true description: "Specify your robot's dimensions and how it is positioned in space." --- -Before you can use the motion planning or navigation services, you need to create a description of your machine's dimensions and how it is positioned relative to its surroundings. +Before you can use the motion planning or navigation with your machine, you need to create a description of your machine's dimensions and how it is positioned relative to its surroundings. The position and orientation readings returned by a component such as an accelerometer or a robot arm have no meaning without a reference frame. Use Viam's frame system to define a coordinate system for your machine, and configure the geometries of your machine's components. @@ -105,7 +105,7 @@ This allows `viam-server` to correctly calculate the position of the end of the This is the origin `(0,0,0)` of the arm reference frame. 1. Measure between these two points. For example, if the arm origin is 10 centimeters above the gantry/world origin, the translation is (0.00, 0.00, 0.10). -1. Configure the gantry reference frame and the arm reference frame as per the instructions in the section above, but set the `parent` of the arm as the gantry, and supply the translation you measured. +1. Configure the gantry reference frame and the arm reference frame according to the instructions in the section above, but set the `parent` of the arm as the gantry, and supply the translation you measured. {{< tabs >}} {{% tab name="Frame Editor" %}} diff --git a/docs/operate/mobility/move-arm/move-robot-arm.md b/docs/operate/mobility/move-arm/move-robot-arm.md index 0bf8b9b848..3f909c4590 100644 --- a/docs/operate/mobility/move-arm/move-robot-arm.md +++ b/docs/operate/mobility/move-arm/move-robot-arm.md @@ -22,14 +22,7 @@ cost: "8400" In this guide you'll use Viam's Python or Go SDK to get the current position of your robot arm and issue movement commands. -{{< alert title="In this page" color="tip" >}} - -1. [Access the arm](#access-the-arm) -1. [Move the arm](#move-the-arm) - -{{< /alert >}} - -## Requirements +## Prerequisites You need the following hardware to complete this tutorial: diff --git a/docs/operate/mobility/use-input-to-act.md b/docs/operate/mobility/use-input-to-act.md index 9da33f2fad..9a41b69fbb 100644 --- a/docs/operate/mobility/use-input-to-act.md +++ b/docs/operate/mobility/use-input-to-act.md @@ -37,7 +37,7 @@ This may include sensors, cameras, motors, bases, arms, gantries, servos, grippe {{% tablestep %}} **1. Start building your app** -Depending on your use case, see [Create a web app](/operate/control/web-app/), [Create a mobile app](/operate/control/mobile-app/), or [Create a headless app](/operate/contro/headless-app/) for information on installing an SDK and connecting your code to your machine. +Depending on your use case, see [Create a web app](/operate/control/web-app/), [Create a mobile app](/operate/control/mobile-app/), or [Create a headless app](/operate/control/headless-app/) for information on installing an SDK and connecting your code to your machine. {{% /tablestep %}} {{% tablestep %}}