diff --git a/.github/workflows/lexi-lint.yml b/.github/workflows/lexi-lint.yml index d68a8ae296..058678933a 100644 --- a/.github/workflows/lexi-lint.yml +++ b/.github/workflows/lexi-lint.yml @@ -17,7 +17,7 @@ jobs: with: ref: ${{github.event.pull_request.head.sha}} fetch-depth: 0 - - uses: npentrel/lexi@v1.1 + - uses: Rebilly/lexi@v2 with: github-token: ${{ secrets.PR_TOKEN }} glob: '**/*.md' diff --git a/assets/extend/modular-resources/configure/add-local-module-config-builder.png b/assets/extend/modular-resources/configure/add-local-module-config-builder.png new file mode 100644 index 0000000000..8c601b831d Binary files /dev/null and b/assets/extend/modular-resources/configure/add-local-module-config-builder.png differ diff --git a/assets/extend/modular-resources/configure/add-local-module-create.png b/assets/extend/modular-resources/configure/add-local-module-create.png new file mode 100644 index 0000000000..b5bec51e17 Binary files /dev/null and b/assets/extend/modular-resources/configure/add-local-module-create.png differ diff --git a/assets/extend/modular-resources/configure/add-local-module-csi-cam.png b/assets/extend/modular-resources/configure/add-local-module-csi-cam.png new file mode 100644 index 0000000000..7476aeea4a Binary files /dev/null and b/assets/extend/modular-resources/configure/add-local-module-csi-cam.png differ diff --git a/assets/extend/modular-resources/configure/add-local-module-list.png b/assets/extend/modular-resources/configure/add-local-module-list.png new file mode 100644 index 0000000000..3de8f61394 Binary files /dev/null and b/assets/extend/modular-resources/configure/add-local-module-list.png differ diff --git a/assets/services/ml-models-service.png b/assets/services/ml-models-service.png deleted file mode 100644 index 70aa6028ea..0000000000 Binary files a/assets/services/ml-models-service.png and /dev/null differ diff --git a/assets/services/vision/color_detector.png b/assets/services/vision/color_detector.png deleted file mode 100644 index ecf8d7df74..0000000000 Binary files a/assets/services/vision/color_detector.png and /dev/null differ diff --git a/assets/services/vision/detector_3d_segmenter.png b/assets/services/vision/detector_3d_segmenter.png deleted file mode 100644 index 30083de135..0000000000 Binary files a/assets/services/vision/detector_3d_segmenter.png and /dev/null differ diff --git a/assets/services/vision/mlmodel.png b/assets/services/vision/mlmodel.png deleted file mode 100644 index 5da9a8f0d4..0000000000 Binary files a/assets/services/vision/mlmodel.png and /dev/null differ diff --git a/assets/services/vision/obstacles_pointcloud.png b/assets/services/vision/obstacles_pointcloud.png deleted file mode 100644 index 8b609232ac..0000000000 Binary files a/assets/services/vision/obstacles_pointcloud.png and /dev/null differ diff --git a/assets/tutorials/confetti-bot/app-board-create.png b/assets/tutorials/confetti-bot/app-board-create.png deleted file mode 100644 index 93a18dfa10..0000000000 Binary files a/assets/tutorials/confetti-bot/app-board-create.png and /dev/null differ diff --git a/assets/tutorials/tipsy/app-board-create.png b/assets/tutorials/tipsy/app-board-create.png deleted file mode 100644 index aa793a2f2b..0000000000 Binary files a/assets/tutorials/tipsy/app-board-create.png and /dev/null differ diff --git a/assets/tutorials/tipsy/app-motor-create.png b/assets/tutorials/tipsy/app-motor-create.png deleted file mode 100644 index f1748535a9..0000000000 Binary files a/assets/tutorials/tipsy/app-motor-create.png and /dev/null differ diff --git a/assets/tutorials/tipsy/app-service-ml-create.png b/assets/tutorials/tipsy/app-service-ml-create.png deleted file mode 100644 index 0d68ce60fa..0000000000 Binary files a/assets/tutorials/tipsy/app-service-ml-create.png and /dev/null differ diff --git a/assets/tutorials/tipsy/app-service-vision-create.png b/assets/tutorials/tipsy/app-service-vision-create.png deleted file mode 100644 index 3c70df5b3e..0000000000 Binary files a/assets/tutorials/tipsy/app-service-vision-create.png and /dev/null differ diff --git a/docs/extend/modular-resources/_index.md b/docs/extend/modular-resources/_index.md index 2c69031b72..61b4e367df 100644 --- a/docs/extend/modular-resources/_index.md +++ b/docs/extend/modular-resources/_index.md @@ -1,5 +1,5 @@ --- -title: "Integrate Modular Resources into your Robot" +title: "Extend Viam with Modular Resources" linkTitle: "Modular Resources" weight: 10 type: "docs" @@ -35,7 +35,7 @@ Once the module has been uploaded to the Registry, you can [deploy the module](/ ### Uploading to Viam Registry After you finish programming your module, you can [upload your module to the Viam registry](/extend/modular-resources/upload/) to make it available for deployment to robots. -As part of the upload process, you decide whether your module is *public* (visible to all users) or *private* (visible only to other members of your [organization](/manage/fleet/organizations/)). +As part of the upload process, you decide whether your module is *private* (visible only to other members of your [organization](/manage/fleet/organizations/)), or *public* (visible to all Viam users). You can see details about each module in the [Viam registry](https://app.viam.com/registry) on its module details page. See the [Odrive module](https://app.viam.com/module/viam/odrive) for an example. @@ -47,7 +47,8 @@ When you make changes to your module, you can [uploaded the newer version](/exte Once you [upload a module to the Viam registry](/extend/modular-resources/upload/), you can [deploy the module](/extend/modular-resources/configure/) to any robot in your organization from [the Viam app](https://app.viam.com/). Navigate to your robot's **Configuration** tab, click the **+ Create component** button, then start typing the name of the module you would like to deploy. -If you uploaded your module and set its visibility to private, the module will only appear for users within your [organization](/manage/fleet/organizations/). + +By default, a newly-created module is *private*, meaning that the module will only appear for users within your [organization](/manage/fleet/organizations/), but you can later [update your module](/extend/modular-resources/upload/#update-an-existing-module) to set it to be *public*, which makes your module available to all Viam users. When you deploy a module to your robot, you can [choose how to update that module](/extend/modular-resources/configure/#configure-version-update-management-for-a-registry-module) when new versions become available. diff --git a/docs/extend/modular-resources/configure.md b/docs/extend/modular-resources/configure.md index 0825ed7547..8444d317a8 100644 --- a/docs/extend/modular-resources/configure.md +++ b/docs/extend/modular-resources/configure.md @@ -9,7 +9,8 @@ no_list: true --- You can extend Viam by adding a module on your robot that provides one or more {{< glossary_tooltip term_id="resource" text="modular resources" >}} ([components](/components/) or [services](/services/)). -You can [add a module from the Viam registry](#add-a-module-from-the-viam-registry), or you can [code your own module and add it to your robot locally](#add-a-local-module-to-your-robot). + +You can [add a module from the Viam registry](#add-a-module-from-the-viam-registry), or you can [add a local module](#local-modules). See [Key Concepts of Modular Resource APIs](/extend/modular-resources/key-concepts/) for more information. @@ -199,46 +200,89 @@ The custom model is configured as a component with the name "my-realsense". {{% /tab %}} {{% /tabs %}} -## Add a local module to your robot +## Local modules -If you are developing your own modular resource, and intend to deploy it to your robot locally, first follow [these steps](/extend/modular-resources/create/) to code your own module and generate an executable. -If you are using a pre-built modular resource, make sure you install the module and determine the filename of [the module's executable](/extend/modular-resources/create/#compile-the-module-into-an-executable). +If you wish to add a module to your robot without uploading it to the Viam registry, you can add your module as a *local module*. -Follow these steps to configure a module and its modular resources locally: +You can add your own custom modules as local modules, or you can add pre-built modules written by other Viam users. -1. [Save the executable](#make-sure-viam-server-can-access-your-executable) in a location your `viam-server` instance can access. -2. [Add a **module**](#configure-your-module) referencing this executable to the configuration of your robot. -3. [Add a new component or service](#configure-your-modular-resource) referencing the modular resource provided by the configured **module** to the configuration of your robot. +### Prepare a local module -### Make sure `viam-server` can access your executable +First determine the module you wish to add as a local module: -Ensure that your module executable is saved where the instance of `viam-server` behind your robot can read and execute it. +- If you are adding your own custom module, be sure that you have followed the steps to [create your own module](/extend/modular-resources/create/) to code and compile your module and generate an executable. +- If you are using a pre-built module, make sure you have installed the module and determined the filename of [the module's executable](/extend/modular-resources/create/#compile-the-module-into-an-executable). -For example, if you are running `viam-server` on an Raspberry Pi, you'll need to save the module on the Pi's filesystem. +Then, ensure that `viam-server` is able to find and run the executable: -Obtain the real (absolute) path to the executable file on your computer's filesystem by running the following command in your terminal: +- Ensure that the module executable is saved to a location on the filesystem of your robot that `viam-server` can access. + For example, if you are running `viam-server` on an Raspberry Pi, you must save the module executable on the Pi's filesystem. +- Ensure that this file is executable (runnable) with the following command: -``` shell -realpath / -``` + ``` shell + sudo chmod a+rx + ``` + +See the instructions to [compile your module into an executable](/extend/modular-resources/create/#compile-the-module-into-an-executable) for more information. + +### Add a local module + +To add a local module on your robot: + +1. Navigate to the **Config** tab of your robot's page on [the Viam app](https://app.viam.com). + - If you are adding a modular [component](/components/), click the **Components** subtab and click **Create component**. + - If you are adding a modular [service](/services/), click the **Services** subtab and click **Create service**. + +1. Then, select the `local modular resource` type from the list. + + {{}} + +1. On the next screen: + - Select the type of modular resource provided by your module, such as a [camera](/components/camera/), from the drop down menu. + - Enter the {{< glossary_tooltip term_id="model-namespace-triplet" text="model namespace triplet">}} of your modular resource's [model](/extend/modular-resources/key-concepts/#models). + If you are adding a pre-built modular resource, the model triplet should be provided for you in the module's documentation. + - Enter a name for this instance of your modular resource. + This name must be different from the module name. + + {{}} + +1. Click **Create** to create the modular resource provided by the local module. -### Configure your module +You can also add the module directly, without first adding its modular component or service: -To configure your new *module* on your robot, navigate to the **Config** tab of your robot's page on [the Viam app](https://app.viam.com) and click on the **Modules** subtab. +1. Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). +1. Click on the **Modules** subtab. +1. Scroll to the **Add local module** section. +1. Enter a **Name** for this instance of your modular resource. +1. Enter the [module's executable path](/extend/modular-resources/create/#compile-the-module-into-an-executable). + This path must be the absolute path to the executable on your robot's filesystem. +1. Then, click the **Add module** button, and click **Save config**. + + {{}} + + This example shows the configuration for adding a [CSI camera](/extend/modular-resources/examples/csi/) as a local module. + +## Configure a local module + +Once you have added a modular resource to your robot, you can view and configure the module itself from the **Modules** subtab: + +1. Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). +1. Click on the **Modules** subtab. + Local modules you have added to your robot appear under the **Local** section. The following properties are available for modules: | Name | Type | Inclusion | Description | | ---- | ---- | --------- | ----------- | `name` | string | **Required**| Name of the module you are registering. | -`executable_path` | string | **Required**| The robot's computer's filesystem path to the module executable. | +`executable_path` | string | **Required**| The absolute path to the executable on your robot's filesystem. | Add these properties to your module's configuration: {{< tabs >}} {{% tab name="Config Builder" %}} -{{< imgproc src="/program/modular-resources/module-ui-config.png" alt="Creation of a new module in the Viam app config builder." resize="1000x" >}} +{{}} {{% /tab %}} {{% tab name="JSON Template" %}} @@ -257,9 +301,9 @@ Add these properties to your module's configuration: {{% /tab %}} {{% /tabs %}} -### Configure your modular resource +### Configure a modular resource -Once you have configured a module as part of your robot configuration, you can add any number of the resources that the module makes available to your robot by adding new components or services configured with your modular resources' [model](/extend/modular-resources/key-concepts/#models). +Once you have added a local module to your robot, you can add any number of the {{< glossary_tooltip term_id="resource" text="resources" >}} provided by that module to your robot by adding new components or services that use your modular resources' [model](/extend/modular-resources/key-concepts/#models). The following properties are available for modular resources: diff --git a/docs/extend/modular-resources/create/_index.md b/docs/extend/modular-resources/create/_index.md index dd73c9fbe5..79af668231 100644 --- a/docs/extend/modular-resources/create/_index.md +++ b/docs/extend/modular-resources/create/_index.md @@ -15,7 +15,7 @@ A common use case for modular resources is to create a new [model](/extend/modul Once you have created your modular resource, you can use the [Viam CLI](/manage/cli/) to [upload your modular resource](/extend/modular-resources/upload/) to the [Viam registry](https://app.viam.com/registry), to share it with other Viam users or just to other users in your organization. You can also configure [automatic uploads of new versions of your module](/extend/modular-resources/upload/#update-an-existing-module-using-a-github-action) as part of a continuous integration (CI) workflow, using a GitHub Action. -Alternatively, you can add your module locally to your robot without uploading to the Viam registry. +You can also add your module to your robot as a [local module](/extend/modular-resources/configure/#local-modules), without uploading it to the Viam registry. ## Create a custom module @@ -468,7 +468,7 @@ Otherwise, the class won’t instantiate. ### Compile the module into an executable -To [add a module](/extend/modular-resources/configure/#configure-your-module) to the configuration of your robot, you need to have an [executable](https://en.wikipedia.org/wiki/Executable) that runs your module when executed, can take a local socket as a command line argument, and cleanly exits when sent a termination signal. +To [add a module](/extend/modular-resources/configure/) to the configuration of your robot, you need to have an [executable](https://en.wikipedia.org/wiki/Executable) that runs your module when executed, can take a local socket as a command line argument, and cleanly exits when sent a termination signal. Your options for completing this step are flexible, as this file does not need to be in a raw binary format. diff --git a/docs/extend/modular-resources/examples/csi.md b/docs/extend/modular-resources/examples/csi.md index 78fe6d6042..f9adeeb262 100644 --- a/docs/extend/modular-resources/examples/csi.md +++ b/docs/extend/modular-resources/examples/csi.md @@ -123,6 +123,8 @@ Next, add the following JSON object to your components array to configure a `csi {{% /tab %}} {{< /tabs >}} +For more information, see [installing local modules](/extend/modular-resources/configure/#local-modules). + Edit and fill in the attributes to configure your component. The following attributes are available for the `viam:camera:csi` model: @@ -138,3 +140,5 @@ The following attributes are available for the `viam:camera:csi` model: Then, save the config. Check the [**Logs** tab](/program/debug/) of your robot in the Viam app to make sure your camera has connected and no errors are being raised. + +For more information, see [installing local modules](/extend/modular-resources/configure/#local-modules). diff --git a/docs/extend/modular-resources/examples/custom-arm.md b/docs/extend/modular-resources/examples/custom-arm.md index fdf6809366..ff60ee01dd 100644 --- a/docs/extend/modular-resources/examples/custom-arm.md +++ b/docs/extend/modular-resources/examples/custom-arm.md @@ -218,7 +218,7 @@ The best practice with the Python SDK is to put `pass` or raise an `NotImplement ### Compile the module into an executable -To [add a module](/extend/modular-resources/configure/#configure-your-module) to the configuration of your robot, you need to have an [executable](https://en.wikipedia.org/wiki/Executable) that runs your module when executed, can take a local socket as a command line argument, and cleanly exits when sent a termination signal. +To [add a module](/extend/modular-resources/configure/) to the configuration of your robot, you need to have an [executable](https://en.wikipedia.org/wiki/Executable) that runs your module when executed, can take a local socket as a command line argument, and cleanly exits when sent a termination signal. Your options for completing this step are flexible, as this file does not need to be in a raw binary format. diff --git a/docs/extend/modular-resources/upload/_index.md b/docs/extend/modular-resources/upload/_index.md index 363f1719b0..979b53e179 100644 --- a/docs/extend/modular-resources/upload/_index.md +++ b/docs/extend/modular-resources/upload/_index.md @@ -55,7 +55,7 @@ To upload your custom module to the [Viam registry](https://app.viam.com/registr visibility string Required - Whether the module is visible to all Viam users (public), or accessible only to members of your organization (private). You can change this setting later using the viam module update command.

Default: private + Whether the module is accessible only to members of your organization (private), or visible to all Viam users (public). You can change this setting later using the viam module update command.

Default: private url @@ -102,7 +102,7 @@ To upload your custom module to the [Viam registry](https://app.viam.com/registr ``` {{% alert title="Important" color="note" %}} - If you are publishing a public module (`visibility: "public"`), the [namespace of your model](/extend/modular-resources/key-concepts/#naming-your-model) must match the [namespace of your organization](/manage/fleet/organizations/#create-a-namespace-for-your-organization). + If you are publishing a public module (`"visibility": "public"`), the [namespace of your model](/extend/modular-resources/key-concepts/#naming-your-model) must match the [namespace of your organization](/manage/fleet/organizations/#create-a-namespace-for-your-organization). In the example above, the model namespace is set to `acme` to match the owning organization's namespace. If the two namespaces do not match, the command will return an error. {{% /alert %}} diff --git a/docs/manage/CLI.md b/docs/manage/CLI.md index a4f272d5b0..c9f2bfe6f5 100644 --- a/docs/manage/CLI.md +++ b/docs/manage/CLI.md @@ -61,6 +61,13 @@ sudo curl -o /usr/local/bin/viam https://storage.googleapis.com/packages.viam.co sudo chmod a+rx /usr/local/bin/viam ``` +You can also install the Viam CLI using [brew](https://brew.sh/) on Linux `amd64` (Intel `x86_64`): + +```{class="command-line" data-prompt="$"} +brew tap viamrobotics/brews +brew install viam +``` + {{% /tab %}} {{% tab name="Source" %}} @@ -349,7 +356,7 @@ All of the `module` commands accept either the `--org-id` or `--public-namespace * Use the `--public-namespace` argument to supply the [namespace](/manage/fleet/organizations/#create-a-namespace-for-your-organization) of your organization, suitable for uploading your module to the Viam registry and sharing with other users. * Use the `--org-id` to provide your organization ID instead, suitable for sharing your module privately within your organization. -You may use either argument for the `viam module create` command, but must use `--public-namespace` for the `update` and `upload` commands when uploading as a public module (`visibility: "public"`) to the Viam registry. +You may use either argument for the `viam module create` command, but must use `--public-namespace` for the `update` and `upload` commands when uploading as a public module (`"visibility": "public"`) to the Viam registry. ##### Using the `--platform` argument @@ -413,7 +420,7 @@ The `meta.json` file includes the following configuration options: visibility string Required - Whether the module is visible to all Viam users (public), or accessible only to members of your organization (private). You can change this setting later using the viam module update command.

Default: private + Whether the module is accessible only to members of your organization (private), or visible to all Viam users (public). You can change this setting later using the viam module update command.

Default: private url @@ -460,7 +467,7 @@ For example, the following represents the configuration of an example `my-module ``` {{% alert title="Important" color="note" %}} -If you are publishing a public module (`visibility: "public"`), the [namespace of your model](/extend/modular-resources/key-concepts/#naming-your-model) must match the [namespace of your organization](/manage/fleet/organizations/#create-a-namespace-for-your-organization). +If you are publishing a public module (`"visibility": "public"`), the [namespace of your model](/extend/modular-resources/key-concepts/#naming-your-model) must match the [namespace of your organization](/manage/fleet/organizations/#create-a-namespace-for-your-organization). In the example above, the model namespace is set to `acme` to match the owning organization's namespace. If the two namespaces do not match, the command will return an error. {{% /alert %}} diff --git a/docs/program/apis/cloud.md b/docs/program/apis/cloud.md index 459edc7203..9c4d0990ed 100644 --- a/docs/program/apis/cloud.md +++ b/docs/program/apis/cloud.md @@ -67,7 +67,7 @@ The cloud API supports the following methods (among [others](https://python.viam ### ListOrganizations -List the organizations the user is an authorized user of. +List the {{< glossary_tooltip term_id="organization" text="organizations" >}} the user is an authorized user of. {{< tabs >}} {{% tab name="Python" %}} @@ -91,7 +91,7 @@ For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/ ### ListOrganizationMembers -List the members and invites of the organization that you are currently authenticated to. +List the members and invites of the {{< glossary_tooltip term_id="organization" text="organizations" >}} that you are currently authenticated to. {{< tabs >}} {{% tab name="Python" %}} @@ -117,7 +117,7 @@ For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/ ### GetOrganizationNamespaceAvailability -Check the availability of an organization namespace. +Check the availability of an {{< glossary_tooltip term_id="organization" text="organization" >}} namespace. {{< tabs >}} {{% tab name="Python" %}} @@ -188,9 +188,289 @@ For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/ {{% /tab %}} {{< /tabs >}} +### CreateLocation + +Create and name a {{< glossary_tooltip term_id="location" text="location" >}} under the organization you are currently authenticated to. +Optionally, put the new location under a specified parent location. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `name` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): Name of the new location. +- `parent_location_id` [(Optional[string])](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): Optional parent location to put the location under. +Defaults to creating a location in your organization at root level if you do not provide a location ID. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid name (such as "") or invalid parent location ID is passed. + +**Returns:** + +- [(viam.proto.app.Location)](https://python.viam.dev/autoapi/viam/proto/app/index.html#viam.proto.app.Location): The newly created location. + +```python {class="line-numbers linkable-line-numbers"} +my_new_location = await cloud.create_location(name="Robotville", parent_location_id="111ab12345") +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.create_location). + +{{% /tab %}} +{{< /tabs >}} + +### GetLocation + +Get a {{< glossary_tooltip term_id="location" text="location" >}} by its location ID. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `location_id` [(Optional[string])](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the location to get. +Defaults to the location ID provided at `AppClient` instantiation. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed, or if one isn't passed and no location ID was provided at `AppClient` instantiation. + +**Returns:** + +- [(viam.proto.app.Location)](https://python.viam.dev/autoapi/viam/proto/app/index.html#viam.proto.app.Location): The location corresponding to the provided ID. + +```python {class="line-numbers linkable-line-numbers"} +location = await cloud.get_location(location_id="123ab12345") +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.get_location). + +{{% /tab %}} +{{< /tabs >}} + +### UpdateLocation + +Change the name of a {{< glossary_tooltip term_id="location" text="parent location" >}} and/or assign it a new location. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `location_id` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the location to update. +- `name` [Optional(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): Optional new name to update the location name to. +If nothing is passed, the name is not changed. +- `parent_location_id` [Optional(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): Optional ID of the new location to move the location to. +If nothing is passed, the location does not move. +If an empty string is passed, the location moves up to the top level. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed, or if one isn't passed and no location ID was provided at `AppClient` instantiation. + +**Returns:** + +- [(viam.proto.app.Location)](https://python.viam.dev/autoapi/viam/proto/app/index.html#viam.proto.app.Location): The newly updated location. + +```python {class="line-numbers linkable-line-numbers"} +# The following line takes the location with ID "abc12abcde" and moves it +# to be a sub-location of the location with ID "xyz34xxxxx" +my_updated_location = await cloud.update_location( + location_id="abc12abcde", + name="", + parent_location_id="xyz34xxxxx", +) + +# The following line changes the name of the location without changing its parent location +my_updated_location = await cloud.update_location( + location_id="abc12abcde", + name="Land Before Robots" +) + +# The following line moves the location back up to be a top level location without changing its name +my_updated_location = await cloud.update_location( + location_id="abc12abcde", + name="", + parent_location_id="" +) +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.update_location). + +{{% /tab %}} +{{< /tabs >}} + +### DeleteLocation + +Delete a {{< glossary_tooltip term_id="location" text="location" >}}. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `location_id` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the location to delete. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed. + +**Returns:** + +- None + +```python {class="line-numbers linkable-line-numbers"} +await cloud.delete_location(location_id="abc12abcde") +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.delete_location). + +{{% /tab %}} +{{< /tabs >}} + +### ListLocations + +Get a list of all {{< glossary_tooltip term_id="location" text="locations" >}} under the organization you are currently authenticated to. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- None + +**Returns:** + +- (List[[viam.proto.app.Location](https://python.viam.dev/autoapi/viam/proto/app/index.html#viam.proto.app.Location)]): The list of locations. + +```python {class="line-numbers linkable-line-numbers"} +locations = await cloud.list_locations() +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.list_locations). + +{{% /tab %}} +{{< /tabs >}} + +### LocationAuth + +Get a location’s `LocationAuth` (location secret or secrets). + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `location_id` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the location to retrieve `LocationAuth` from. +Defaults to the location ID provided at `AppClient` instantiation. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed, or if one isn't passed and no location ID was provided at `AppClient` instantiation. + +**Returns:** + +- [(viam.proto.app.LocationAuth)](https://python.viam.dev/autoapi/viam/gen/app/v1/app_pb2/index.html#viam.gen.app.v1.app_pb2.LocationAuth): The `LocationAuth` containing location secrets and secret IDs. + +```python {class="line-numbers linkable-line-numbers"} +loc_auth = await cloud.location_auth(location_id="123xy12345") +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.location_auth). + +{{% /tab %}} +{{< /tabs >}} + +### CreateLocationSecret + +Create a new location secret. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `location_id` [(Optional[string])](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the location to generate a new secret for. + Defaults to the location ID provided at `AppClient` instantiation. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed, or if one isn't passed and no location ID was provided at `AppClient` instantiation. + +**Returns:** + +- [(viam.proto.app.LocationAuth)](https://python.viam.dev/autoapi/viam/gen/app/v1/app_pb2/index.html#viam.gen.app.v1.app_pb2.LocationAuth): The specified location's `LocationAuth` containing the newly created secret. + +```python {class="line-numbers linkable-line-numbers"} +new_loc_auth = await cloud.create_location_secret() +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.create_location_secret). + +{{% /tab %}} +{{< /tabs >}} + +### DeleteLocationSecret + +Delete a location secret. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `location_id` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the location to delete the secret from. + Defaults to the location ID provided at `AppClient` instantiation. +- `secret_id` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): The `id` of the secret to delete (not the secret string itself). + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed, or if one isn't passed and no location ID was provided at `AppClient` instantiation. + +**Returns:** + +- [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): + +```python {class="line-numbers linkable-line-numbers"} +await cloud.delete_location_secret(secret_id="abcd123-456-7890ab-cxyz98-989898xyzxyz") +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.delete_location_secret). + +{{% /tab %}} +{{< /tabs >}} + +### GetRobot + +Get a robot by its ID. + +{{< tabs >}} +{{% tab name="Python" %}} + +**Parameters:** + +- `robot_id` [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): ID of the robot to get. + +**Raises:** + +- `GRPCError`: This error is raised if an invalid location ID is passed, or if one isn't passed and no location ID was provided at `AppClient` instantiation. + +**Returns:** + +- [(string)](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str): The robot. + +```python {class="line-numbers linkable-line-numbers"} +robot = await cloud.get_robot(robot_id="1a123456-x1yz-0ab0-a12xyzabc") +``` + +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.get_robot). + +{{% /tab %}} +{{< /tabs >}} + ### NewRobot -Create a new robot. +Create a new {{< glossary_tooltip term_id="robot" text="robot" >}}. {{< tabs >}} {{% tab name="Python" %}} @@ -213,7 +493,7 @@ Create a new robot. new_robot_id = await cloud.new_robot(name="beepboop") ``` -For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.get_organization_namespace_availability). +For more information, see the [Python SDK Docs](https://python.viam.dev/autoapi/viam/app/app_client/index.html#viam.app.app_client.AppClient.new_robot). {{% /tab %}} {{< /tabs >}} diff --git a/docs/program/apis/sessions.md b/docs/program/apis/sessions.md index cf48370682..8fc3e73e24 100644 --- a/docs/program/apis/sessions.md +++ b/docs/program/apis/sessions.md @@ -3,47 +3,55 @@ title: "Session Management with Viam's Client SDKs" linkTitle: "Session Management" weight: 20 type: "docs" -description: "How to use the session management API with Viam's Client SDKs." +description: "Manage sessions between your robot and clients connected through Viam's SDKs." tags: ["client", "sdk", "viam-server", "networking", "apis", "robot api", "session", "sessions", "session management"] --- -When controlling a robot or fleet with Viam, you want a way to understand the presence of the clients that are communicating with and authenticated to each robot's `viam-server`. -The period of time during which these clients are present is called a *session*. +When you connect to a robot using an SDK, the SDK connects to the robot's `viam-server` instance as a _client_. +The period of time during which a client is connected to a robot is called a _session_. -Session management: +_Session management_ is a presence mechanism that allows you to manage the clients that are authenticated and communicating with a robot's `viam-server` instance. -- allows a client to express that it is actively connected or authenticated to `viam-server` on your robot -- supports stopping moving components when the connection is no longer active. - -*Session management* is a presence mechanism between a client and `viam-server`. -Session management allows for safer operation of robots that physically move. +As a safety precaution, the default session management configuration ensures that a robot only moves when a client is actively connected. +This is especially important for robots that physically move. For example, imagine a wheeled rover gets a [`SetPower()`](/components/base/#setpower) command as the last input from a client before the connection to the robot is interrupted. -Without session management, the API request from the client sets the flow of electricity to the motors of the robot and then does not time out, causing the robot to continue driving forever, colliding with objects and people. +Without session management, the API request from the client would cause the rover's motors to move, causing the robot to continue driving forever and potentially colliding with objects and people. + +If you want to manage operations differently, you can manage your robot's client sessions yourself. +The Session Management API provides functionality for -With default configuration, sessions are automatically managed for you with Viam's `SessionsClient`. -If you want to manage sessions yourself, use Viam's sessions management API. +- clients to notify to the robot that the client is actively authenticated and connected +- the robot to stop moving components when a session ends ### The `SessionsClient` -A Viam robot has many clients because a client is anything that is receiving the information served by `viam-server` running on the robot, which includes the primary part, sub-parts, client SDKs, and more. -A *client* of a Viam robot could be an SDK script controlling the robot, an input controller, or just the different resources on the robot talking amongst themselves. -For example, if you use Viam's module registry to [add modular resources to your robot](/extend/modular-resources/), the clients of your robot will include the "model servers" you instantiate on your robot for individual resources. +A _client_ of a Viam robot can be a program using an SDK to control the robot, or all the different resources on the robot, including all {{< glossary_tooltip term_id="part" text="parts" >}} and sub-parts, like an input controller and a base, communicating. + +For example, if you use Viam's module registry to [add modular resources to your robot](/extend/modular-resources/), the clients of your robot will include the model servers you instantiate on your robot for individual resources, as well as the SDKs you are using to program the modular resources. Viam's session management API's `SessionsClient` is a built-in solution that manages the connection between your robot's clients and your robot. -With the `SessionsClient`, if the robot does not receive a signal from the client at regular intervals, it safely stops until the connection is reestablished. -Your client of the session management API maintains the session, telling the `viam-server` instance that it is still present every so often; in other words, staying within the *heartbeat* window. +If you connect to your robot using one of Viam's SDKs, the resulting client will automatically maintain the session by sending a _heartbeat_ notifying the robot's `viam-server` instance of its continued presence. +The `SessionsClient` on the robot maintains an overview of all sessions based on the clients' heartbeat messages. + +If the robot does not receive a signal from the client in the expected interval, the robot ends the session and stop all resources that are marked for safety monitoring and have been last used by that session. +That means if a client sends a command to a robot to move the motors and then loses the connection, the robot will stop moving. + +{{< alert title="Caution" color="caution" >}} +If a resource was used by client A and then by client B, and client A disconnects, the resource will not be stopped, regardless of possibly ongoing commands initiated by client A. +{{< /alert >}} + +A disconnected client will attempt to establish a new session immediately prior to the next operation it performs. #### Heartbeats -A *heartbeat* is a signal that indicates robot connectivity. -Essentially, "heartbeats" are a Viam robot's way of letting a user reading data from it know the different parts of it are "alive." +A _heartbeat_ is a signal that indicates robot connectivity. +Essentially, heartbeats are a client's way of letting a robot know that they are still connected. -Heartbeats are sent automatically from Viam's Go, Python, and TypeScript client SDKs unless you disable this with the session management API, or session management is not implemented by the server in question. +Heartbeats are sent automatically from Viam's SDKs unless you disable them with the session management API or session management is not implemented by the server in question. Heartbeats are automatically sent at an interval that is one fifth of the heartbeat window. For example, if the heartbeat window is 5 seconds, clients will each send a heartbeat every 1 second. -You can adjust the heartbeat window through the configuration of your robot. -To do so, add Raw JSON to the configuration of your robot in this format: +You can adjust the heartbeat window in the configuration of your robot by adding the following to your robot's Raw JSON configuration: ``` json ... // components {...}, services {...}, @@ -57,37 +65,17 @@ To do so, add Raw JSON to the configuration of your robot in this format: The default heartbeat window is 2 seconds if this configuration is omitted. -If you choose to use the session management API to manage sessions, your client must send at least one session heartbeat within the window you set. -As soon as your window lapses or expires, the server will safely stop all resources that are marked for safety monitoring that have been last used by that session, and no others. -A lapsed client will attempt to establish a new session immediately prior to the next operation it performs. - -## Usage - -Usage of the session management API differs across [Viam's SDKS](/program/). - -### Access the session management API - -To manage sessions on-robot manually, you can use the following client SDKs: - -{{< tabs >}} -{{% tab name="Go" %}} - -To enable the [Session Management API](https://pkg.go.dev/go.viam.com/rdk/session) the Go Client SDK provides, [disable the default behavior of sessions](#disable-default-session-management). +If you manually manage sessions, each client must send at least one heartbeat within the window you set. -{{% /tab %}} -{{% tab name="Other SDKs" %}} +## Manage sessions with the session management API -The session management API is not currently provided in the Python or TypeScript SDKs. +The [Session Management API](https://pkg.go.dev/go.viam.com/rdk/session) is not currently provided in the Python or TypeScript SDKs. Use the Go Client SDK instead. -{{% /tab %}} -{{% /tabs %}} - -### Use the session management API to manually manage sessions +To manage your session with the session management API: -First, use your [`RobotClient()`](/program/apis/#robot-api) instance to access the [`SessionsClient`](https://pkg.go.dev/go.viam.com/rdk/session) within your client SDK program. -This is a [gRPC](https://grpc.io/) client that `viam-server` instantiates at robot runtime. -Find `SessionsClient` defined on [GitHub](https://github.com/viamrobotics/rdk/blob/main/robot/client/client.go). +1. [Disable the default session management](#disable-default-session-management) +1. [Use the session management API to manually manage sessions](#use-the-session-management-api-to-manually-manage-sessions) ### Disable default session management @@ -129,3 +117,9 @@ disableSessions: true This option allows you to have full control over sessions management. After disabling the client, you must now manage each of your sessions manually with the session management API. You can do this with Viam's [client SDKs](https://pkg.go.dev/go.viam.com/rdk/session). + +### Use the session management API to manually manage sessions + +Use your [`RobotClient()`](/program/apis/#robot-api) instance to access the [`SessionsClient`](https://pkg.go.dev/go.viam.com/rdk/session) within your client SDK program. +This is a [gRPC](https://grpc.io/) client that `viam-server` instantiates at robot runtime. +Then, define your own [`SessionsClient`](https://github.com/viamrobotics/rdk/blob/main/robot/client/client.go). diff --git a/docs/services/base-rc/_index.md b/docs/services/base-rc/_index.md index 9eda6df84d..bf2c671d00 100644 --- a/docs/services/base-rc/_index.md +++ b/docs/services/base-rc/_index.md @@ -1,6 +1,6 @@ --- title: "Base Remote Control Service" -linkTitle: "Remote Control" +linkTitle: "Base Remote Control" weight: 60 type: "docs" description: "The base remote control service allows you to remotely control a base with an input controller like a gamepad." @@ -33,12 +33,11 @@ You must configure a [base](/components/base/) with a [movement sensor](/compone {{% tab name="Config Builder" %}} Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). -Click on the **Services** subtab and navigate to the **Create service** menu. -Select the type `Navigation` and enter a name for your service. +Click the **Services** subtab, then click **Create service** in the lower-left corner. +Select the type `Base Remote Control`. +Enter a name for your service, then click **Create**. -Click **Create service**: - -![An example configuration for a Base Remote Control service in the Viam app Config Builder.](/services/base-rc/base-rc-ui-config.png) +![An example configuration for a base remote control service in the Viam app Config Builder.](/services/base-rc/base-rc-ui-config.png) {{% /tab %}} {{% tab name="JSON Template" %}} @@ -72,8 +71,8 @@ Click **Create service**: {{% /tab %}} {{< /tabs >}} -Next, add the JSON `"attributes"` you want the service to have. -The following attributes are available for Base Remote Control services: +Edit and fill in the attributes as applicable. +The following attributes are available for base remote control services: | Name | Type | Inclusion | Description | | ---- | ---- | --------- | ----------- | diff --git a/docs/services/data/configure-data-capture.md b/docs/services/data/configure-data-capture.md index 86bb60f9b7..85e5015ecf 100644 --- a/docs/services/data/configure-data-capture.md +++ b/docs/services/data/configure-data-capture.md @@ -12,10 +12,10 @@ tags: ["data management", "cloud", "sync"] To capture data from one or more robots, you must first add the [data management service](../): -1. On your robot's **Config** page, navigate to the **Services** tab. -2. At the bottom of the page you can create a service. +1. From your robot's **Config** tab, navigate to the **Services** subtab. +2. Click **Create service** in the lower-left corner of the page. Choose `Data Management` as the type and specify a name for your data management service, for example `data-manager`. -3. Then click `Create Service`. +3. Click **Create**. 4. On the panel that appears, you can manage the capturing and syncing functions individually and specify the interval and directory. If the capture frequency or the directory is not specified, the data management service captures data at the default frequency every 0.1 minutes (after every 6 second interval) in the default `~/.viam/capture` directory. diff --git a/docs/services/ml/_index.md b/docs/services/ml/_index.md index 9eba643eb8..c2fadafe2a 100644 --- a/docs/services/ml/_index.md +++ b/docs/services/ml/_index.md @@ -18,18 +18,10 @@ The ML Model service allows you to deploy machine learning models to your robots {{< tabs >}} {{% tab name="Builder" %}} -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the ML model service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. - -1. Select `mlmodel` as the **Type**. -2. Enter a name as the **Name**. -3. Select `tflite_cpu` as the **Model**. -4. Click **Create Service**. - -![Create a machine learning models service](/services/ml-models-service.png) +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `ML Model` type, then select the `TFLite CPU` model. +Enter a name for your service and click **Create**. You can choose to configure your service with an existing model on the robot or deploy a model onto your robot: diff --git a/docs/services/motion/_index.md b/docs/services/motion/_index.md index a5d789ba80..aef77e50a3 100644 --- a/docs/services/motion/_index.md +++ b/docs/services/motion/_index.md @@ -439,6 +439,13 @@ Translation in obstacles is not supported by the [navigation service](/services/ - `heading` [(Optional[float])](https://docs.python.org/library/typing.html#typing.Optional): The compass heading, in degrees, that the robot's movement sensor should report at the `destination` point.
  • Range: `[0-360)`
  • Default: `None`
- `linear_meters_per_sec` [(Optional[float])](https://docs.python.org/library/typing.html#typing.Optional): The linear velocity in meters per second to target when moving the component.
  • Default: `0.3`
- `angular_deg_per_sec` [(Optional[float])](https://docs.python.org/library/typing.html#typing.Optional): The [angular velocity](https://en.wikipedia.org/wiki/Angular_velocity) in degrees per second to target when turning the component.
  • Default: `60`
+- `configuration` [(Optional[MotionConfiguration])](https://python.viam.dev/autoapi/viam/proto/service/motion/index.html#viam.proto.service.motion.MotionConfiguration): The configuration you want to set across this robot for this motion service. This parameter and each of its fields are optional. + - `vision_services` [([ResourceName])](https://python.viam.dev/autoapi/viam/gen/common/v1/common_pb2/index.html#viam.gen.common.v1.common_pb2.ResourceName): The name you configured for each vision service you want to use while moving this resource. + - `position_polling_frequency_hz` [(float)](https://docs.python.org/3/library/functions.html#float): The frequency in hz to poll the position of the robot. + - `obstacle_polling_frequency_hz` [(float)](https://docs.python.org/3/library/functions.html#float): The frequency in hz to poll the vision service for new obstacles. + - `plan_deviation_m` [(float)](https://docs.python.org/3/library/functions.html#float): The distance in meters that the machine can deviate from the motion plan. + - `linear_m_per_sec` [(float)](https://docs.python.org/3/library/functions.html#float): Linear velocity this machine should target when moving. + - `angular_degs_per_sec` [(float)](https://docs.python.org/3/library/functions.html#float): Angular velocity this machine should target when turning. - `extra` [(Optional\[Dict\[str, Any\]\])](https://docs.python.org/library/typing.html#typing.Optional): Extra options to pass to the underlying RPC call. - `timeout` [(Optional\[float\])](https://docs.python.org/library/typing.html#typing.Optional): An option to set how long to wait (in seconds) before calling a time-out and closing the underlying RPC call. @@ -474,6 +481,13 @@ success = await motion.move_on_globe(component_name=my_base_resource_name, desti - `obstacles` [([]*spatialmath.GeoObstacle)](https://pkg.go.dev/go.viam.com/rdk/spatialmath#GeoObstacle): Obstacles to consider when planning the motion of the component, with each represented as a `GeoObstacle`.
  • Default: `None`
- `linear_meters_per_sec` [(float64)](https://pkg.go.dev/builtin#float64): The linear velocity in meters per second to target when moving the component.
  • Default: `0.3`
- `angular_deg_per_sec` [(float64)](https://pkg.go.dev/builtin#float64): The [angular velocity](https://en.wikipedia.org/wiki/Angular_velocity) in degrees per second to target when turning the component.
  • Default: `60.0`
+- `motionConfig` [(*MotionConfiguration)](https://pkg.go.dev/go.viam.com/rdk/services/motion#MotionConfiguration): The configuration you want to set across this robot for this motion service. This parameter and each of its fields are optional. + - `VisionSvc` [([]resource.Name)](https://pkg.go.dev/go.viam.com/rdk/resource#Name): The name you configured for each vision service you want to use while moving this resource. + - `PositionPollingFreqHz` [(float64)](https://pkg.go.dev/builtin#float64): The frequency in hz to poll the position of the robot. + - `ObstaclePollingFreqHz` [(float64)](https://pkg.go.dev/builtin#float64): The frequency in hz to poll the vision service for new obstacles. + - `PlanDeviationM` [(float64)](https://pkg.go.dev/builtin#float64): The distance in meters that the machine can deviate from the motion plan. + - `LinearMPerSec` [(float64)](https://pkg.go.dev/builtin#float64): Linear velocity this machine should target when moving. + - `AngularDegsPerSec` [(float64)](https://pkg.go.dev/builtin#float64): Angular velocity this machine should target when turning. - `extra` [(map\[string\]interface{})](https://go.dev/blog/maps): Extra options to pass to the underlying RPC call. **Returns:** diff --git a/docs/services/navigation/_index.md b/docs/services/navigation/_index.md index 8b4a9dc427..7449bb1011 100644 --- a/docs/services/navigation/_index.md +++ b/docs/services/navigation/_index.md @@ -33,10 +33,9 @@ Make sure the [movement sensor](/components/movement-sensor/) you use supports [ {{% tab name="Config Builder" %}} Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). -Click on the **Services** subtab and navigate to the **Create service** menu. -Select the type `navigation` and enter a name for your service. - -Click **Create service**: +Click the **Services** subtab, then click **Create service** in the lower-left corner. +Select the type `Navigation`. +Enter a name for your service, then click **Create**. ![An example configuration for a Navigation service in the Viam app Config Builder.](/services/navigation/navigation-ui-config.png) @@ -106,7 +105,7 @@ Click **Create service**: {{% /tab %}} {{< /tabs >}} -Next, add the JSON `"attributes"` you want the service to have. +Edit and fill in the attributes as applicable. The following attributes are available for `Navigation` services: | Name | Type | Inclusion | Description | diff --git a/docs/services/vision/classification.md b/docs/services/vision/classification.md index 598890450a..4a5c259f40 100644 --- a/docs/services/vision/classification.md +++ b/docs/services/vision/classification.md @@ -27,23 +27,15 @@ The types of classifiers supported are: ## Configure an `mlmodel` classifier -To create a `mlmodel` classifier, you need an [ML model service with a suitable model](../../ml/). - -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. +To create an `mlmodel` classifier, you need an [ML model service with a suitable model](../../ml/). {{< tabs >}} {{% tab name="Builder" %}} -1. Select `vision` as the **Type**. -2. Enter a name as the **Name**. -3. Select **ML Model** as the **Model**. -4. Click **Create Service**. - -![Create vision service for mlmodel](/services/vision/mlmodel.png) +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `Vision` type, then select the `ML Model` model. +Enter a name for your service and click **Create**. In your vision service's panel, fill in the **Attributes** field. diff --git a/docs/services/vision/detection.md b/docs/services/vision/detection.md index 02335d6e5a..1340ae369f 100644 --- a/docs/services/vision/detection.md +++ b/docs/services/vision/detection.md @@ -51,19 +51,10 @@ If the color is not reliably detected, increase the `hue_tolerance_pct`. {{< tabs >}} {{% tab name="Builder" %}} -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. -To create a [vision service](/services/vision/): - -1. Select `vision` as the **Type**. -2. Enter a name as the **Name**. -3. Select **Color Detector** as the **Model**. -4. Click **Create Service**. - -![Create vision service for color detector](/services/vision/color_detector.png) +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `ML Model` type, then select the `Color Detector` model. +Enter a name for your service and click **Create**. In your vision service's panel, select the color your vision service will be detecting, as well as a hue tolerance and a segment size (in pixels): @@ -153,21 +144,13 @@ Proceed to [test your detector](#test-your-detector). A machine learning detector that draws bounding boxes according to the specified tensorflow-lite model file available on the robot’s hard drive. To create a `mlmodel` classifier, you need an [ML model service with a suitable model](../../ml/). -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. - {{< tabs >}} {{% tab name="Builder" %}} -1. Select `vision` as the **Type**. -2. Enter a name as the **Name**. -3. Select **ML Model** as the **Model**. -4. Click **Create Service**. - -![Create vision service for mlmodel](/services/vision/mlmodel.png) +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `Vision` type, then select the `ML Model` model. +Enter a name for your service and click **Create**. In your vision service's panel, fill in the **Attributes** field. diff --git a/docs/services/vision/segmentation.md b/docs/services/vision/segmentation.md index 23178b3857..cebc25f508 100644 --- a/docs/services/vision/segmentation.md +++ b/docs/services/vision/segmentation.md @@ -29,19 +29,10 @@ It is slower than other segmenters and can take up to 30 seconds to segment a sc {{< tabs >}} {{% tab name="Builder" %}} -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. -To create a [vision service](/services/vision/): - -1. Select `vision` as the **Type**. -2. Enter a name as the **Name**. -3. Select **Radius Clustering Segmenter** as the **Model**. -4. Click **Create Service**. - -![Create vision service for obstacles_pointcloud](/services/vision/obstacles_pointcloud.png) +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `Vision` type, then select the `Radius Clustering Segmenter` model. +Enter a name for your service and click **Create**. In your vision service's panel, fill in the **Attributes** field. @@ -138,19 +129,10 @@ The label and the pixels associated with the 2D detections become the label and {{< tabs >}} {{% tab name="Builder" %}} -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. -To create a [vision service](/services/vision/): - -1. Select `vision` as the **Type**. -2. Enter a name as the **Name**. -3. Select **Detector to 3D Segmenter** as the **Model**. -4. Click **Create Service**. - -![Create vision service for detector_3d_segmenter](/services/vision/detector_3d_segmenter.png) +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `Vision` type, then select the `Detector to 3D Segmenter` model. +Enter a name for your service and click **Create**. In your vision service's panel, fill in the **Attributes** field. diff --git a/docs/tutorials/get-started/confetti-bot.md b/docs/tutorials/get-started/confetti-bot.md index b98e5d2eaa..31ee54ae1f 100644 --- a/docs/tutorials/get-started/confetti-bot.md +++ b/docs/tutorials/get-started/confetti-bot.md @@ -34,7 +34,7 @@ You can expand on this project to turn a motor based on other types of inputs, s ### Hardware * A macOS or Linux computer -* A [Raspberry Pi](https://a.co/d/bxEdcAT), with a [microSD card](https://www.amazon.com/Lexar-Micro-microSDHC-Memory-Adapter/dp/B08XQ7NGG1/ref=sr_1_13), set up using [these instructions](https://docs.viam.com/installation/prepare/rpi-setup/). +* A [Raspberry Pi](https://a.co/d/bxEdcAT), with a [microSD card](https://www.amazon.com/Lexar-Micro-microSDHC-Memory-Adapter/dp/B08XQ7NGG1/ref=sr_1_13), set up using [these instructions](/installation/prepare/rpi-setup/). * A big button, like [this one](https://www.amazon.com/EG-STARTS-Buttons-Illuminated-Machine/dp/B01LZMANZ7/ref=sxts_b2b_sx_reorder_acb_business). Check the wiring diagram for the specific model you have as you wire the button. * A mini confetti cannon, like [this one](https://www.amazon.com/Confetti-Poppers-Party-Accessory-Pack/dp/B074SP7FZH/ref=sr_1_4) @@ -52,7 +52,7 @@ The STL files we use for 3D printing are adapted to the size of this motor, but * [Python3](https://www.python.org/download/releases/3.0/) * [pip](https://pip.pypa.io/en/stable/#) -* [viam-server](https://docs.viam.com/installation/#install-viam-server) +* [viam-server](/installation/#install-viam-server) * [Viam Python SDK](https://python.viam.dev/) ## Set up your hardware @@ -121,33 +121,31 @@ We named ours ConfettiBot. ![A robot page header in the Viam app, its under the location work, and named ConfettiBot.](/tutorials/confetti-bot/app-name-confettibot.png) -Then navigate to the robot’s **CONFIG** tab to start configuring your components. +Then navigate to the robot’s **Config** tab to start configuring your components. {{< tabs >}} {{% tab name="Builder UI" %}} ### Configure the Pi as a board -Click on the **Components** subtab and navigate to the **Create component** menu. +Click on the **Components** subtab and click **Create component** in the lower-left corner of the page. -Add your {{< glossary_tooltip term_id="board" text="board" >}} with the name `party`, type `board` and model `pi`. -Click **Create Component**. +Add your {{< glossary_tooltip term_id="board" text="board" >}} with type `board` and model `pi`. +Enter `party` for the name of your [board component](/components/board/), then click **Create**. -![Create component panel, with the name attribute filled as party, type attribute filled as board and model attribute filled as pi.](/tutorials/confetti-bot/app-board-create.png) - -You can name your board whatever you want as long as you refer to it the same way in your code, we picked `party` for fun. +You can name your board whatever you want as long as you refer to it the same way in your code; we picked `party` for fun. Your board configuration should now look like this: ![Board component configured in the Viam app, the component tab is named party, with a type attribute board and model attribute pi.](/tutorials/confetti-bot/app-board-attribute.png) ### Configure the motor -Add your [motor](https://docs.viam.com/components/motor/) with the name “start”, type `motor`, and model `gpio`. +Click on the **Components** subtab and click **Create component** in the lower-left corner of the page. +Select `motor` for the type and `gpio` for the model. +Enter `start` for the name of your [motor component](/components/motor/), then click **Create**. Again, we named it “start” to refer to the button being pressed, but this name is up to you as long as you remember the name and use the same name in the code later. -![Create component panel, with the name attribute filled as start, type attribute filled as motor and model attribute filled as gpio.](/tutorials/confetti-bot/app-motor-create.png) - -After clicking **Create Component**, there is a pin assignment type toggle. +After clicking **Create**, there is a pin assignment type toggle. Select **In1/In2** since that is compatible with the type of input our motor controller expects. In the drop downs for A/In1 and B/In2, choose `13 GPIO 27` and `15 GPIO 22` and for PWM choose `11 GPIO 17` corresponding to our wiring. diff --git a/docs/tutorials/projects/bedtime-songs-bot.md b/docs/tutorials/projects/bedtime-songs-bot.md index 62b4ff81d1..4459da14cc 100644 --- a/docs/tutorials/projects/bedtime-songs-bot.md +++ b/docs/tutorials/projects/bedtime-songs-bot.md @@ -63,10 +63,10 @@ First, add your personal computer's webcam to your robot as a [camera](/componen {{< tabs >}} {{% tab name="Builder UI" %}} -Click on the **Components** subtab and navigate to the **Create component** menu. +Click the **Components** subtab, then click **Create component** in the lower-left corner of the page. -Add your [camera](https://docs.viam.com/components/board/) with the name `cam`, type `camera`, and model `webcam`. -Click **Create Component**. +Select `camera` for the type, then select `webcam` for the model. +Enter `cam` for the name of your [camera component](/components/camera/), then click **Create**. ![Creation of a `webcam` camera in the Viam app config builder. The user is selecting the video_path configuration attribute from the drop-down menu](../../tutorials/bedtime-songs-bot/video-path-ui.png) diff --git a/docs/tutorials/projects/guardian.md b/docs/tutorials/projects/guardian.md index 1263dc61b3..087b0e4ec1 100644 --- a/docs/tutorials/projects/guardian.md +++ b/docs/tutorials/projects/guardian.md @@ -260,59 +260,66 @@ scp labels.txt pi@guardian.local:/home/pi/labels.txt {{% tab name="Builder UI" %}} Next, navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). -Click on the **Services** subtab and navigate to the **Create service** menu. +Click the **Services** subtab. 1. **Add an ML model service.** - The [ML model service](/services/ml/) allows you to deploy the provided machine learning model to your robot. - Create an ML model with the name `mlmodel`, the type `mlmodel` and the model `tflite_cpu`. - Then click **Create Service**. + The [ML model service](/services/ml/) allows you to deploy the provided machine learning model to your robot. - In the new ML Model panel, select **Path to Existing Model On Robot** for the **Deployment**. + Click **Create service** in the lower-left corner of the page. + Select type `ML Model`, then select model `TFLite CPU`. + Enter `mlmodel` as the name for your ML model service, then click **Create**. - Then specify the absolute **Model Path** as `/home/pi/effdet0.tflite` and the **Label Path** as `/home/pi/labels.txt`. + In the new ML Model panel, select **Path to existing model on robot** for the **Deployment**. + + Then specify the absolute **Model path** as `/home/pi/effdet0.tflite` and the **Label path** as `/home/pi/labels.txt`. 2. **Add a vision service.** - Next, add a [detector](/services/vision/detection/) as a vision service to be able to make use of the ML model. - Create an vision service with the name `detector`, the type `vision` and the model `mlmodel`. - Then click **Create Service**. + Next, add a [detector](/services/vision/detection/) as a vision service to be able to make use of the ML model. + + Click **Create service** in the lower-left corner of the page. + Select type `Vision`, then select model `ML Model`. + Enter `detector` as the name, then click **Create**. - In the new detector panel, select the `mlmodel` you configured in the previous step. + In the new detector panel, select the `mlmodel` you configured in the previous step. - Click **Save config** in the bottom left corner of the screen. + Click **Save config** in the bottom left corner of the screen. 3. **Add a `transform` camera.** - To be able to test that the vision service is working, add a `transform` camera which will add bounding boxes and labels around the objects the service detects. + To be able to test that the vision service is working, add a `transform` camera which will add bounding boxes and labels around the objects the service detects. - Click on the **Components** subtab and navigate to the **Create component** menu. - Create a [transform camera](/components/camera/transform/) with the name `transform_cam`, the type `camera` and the model `transform`. + Navigate to the **Components** subtab of the **Config** tab. + Click **Create component** in the lower-left corner of the page. - Replace the attributes JSON object with the following object which specifies the camera source that the `transform` camera will be using and defines a pipeline that adds the defined `detector`: + Select `camera` for the type, then select `transform` for the model. + Enter `transform_cam` as the name for your [transform camera](/components/camera/transform/), then click **Create**. - ```json - { - "source": "cam", - "pipeline": [ - { - "type": "detections", - "attributes": { - "detector_name": "detector", - "confidence_threshold": 0.6 - } - } - ] - } - ``` + Replace the attributes JSON object with the following object which specifies the camera source that the `transform` camera will be using and defines a pipeline that adds the defined `detector`: + + ```json + { + "source": "cam", + "pipeline": [ + { + "type": "detections", + "attributes": { + "detector_name": "detector", + "confidence_threshold": 0.6 + } + } + ] + } + ``` - Click **Save config** in the bottom left corner of the screen. + Click **Save config** in the bottom left corner of the screen. {{% /tab %}} {{% tab name="Raw JSON" %}} -Next, on the [`Raw JSON` tab](/manage/configuration/#the-config-tab), replace the configuration with the following configuration which configures the [ML model service](/services/ml/), the [vision service](/services/vision/), and a [transform camera](/components/camera/transform/): +Next, on the [**Raw JSON** tab](/manage/configuration/#the-config-tab), replace the configuration with the following configuration which configures the [ML model service](/services/ml/), the [vision service](/services/vision/), and a [transform camera](/components/camera/transform/): ```json {class="line-numbers linkable-line-numbers" data-line="31-48,50-69"} { diff --git a/docs/tutorials/projects/light-up.md b/docs/tutorials/projects/light-up.md index f7137b7db6..db954503b3 100644 --- a/docs/tutorials/projects/light-up.md +++ b/docs/tutorials/projects/light-up.md @@ -87,43 +87,37 @@ If you want to train your own, you can [train a model](/manage/ml/train-model/). To use the provided Machine Learning model, copy the [effdet0.tflite](https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/effdet0.tflite) file and the [labels.txt](https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/labels.txt) to your project directory. -Click on the **Services** subtab and navigate to the **Create service** menu. +Navigate to the **Services** subtab of your robot's **Config** tab. -1. **Configure the ML model service** +### Configure the ML model service - Add an [mlmodel](/services/ml/) service with the name `people`, type `mlmodel`, and model `tflite_cpu`. - Click **Create service**. +Click **Create service** in the lower-left corner of the page. +Select `ML Model` for the type, then select `TFLite CPU` for the model. +Enter `people` as the name for your [mlmodel](/services/ml/), then click **Create**. - ![Create service panel, with the type attribute filled as mlmodel, name attribute filled as people, and model attribute filled as tflite_cpu.](/tutorials/tipsy/app-service-ml-create.png) +In the new ML Model service panel, configure your service. - In the new ML Model service panel, configure your service. +![mlmodel service panel with empty sections for Model Path, and Optional Settings such as Label Path and Number of threads.](/tutorials/tipsy/app-service-ml-before.png) - ![mlmodel service panel with empty sections for Model Path, and Optional Settings such as Label Path and Number of threads.](/tutorials/tipsy/app-service-ml-before.png) +Select the **Path to existing model on robot** for the **Deployment** field. +Then specify the absolute **Model path** as where your tflite file lives and any **Optional settings** such as the absolute **Label path** as where your labels.txt file lives and the **Number of threads** as `1`. - Select the **Path to Existing Model On Robot** for the **Deployment** field. - Then specify the absolute **Model Path** as where your tflite file lives and any **Optional Settings** such as the absolute **Label Path** as where your labels.txt file lives and the **Number of threads** as 1. +### Configure an mlmodel detector - 1. **Configure an mlmodel detector** +Click **Create service** in the lower-left corner of the page. +For your [vision service](/services/vision/), select type `vision` and model `mlmodel`. +Enter `myPeopleDetector` for the name, then click **Create**. - Add a [vision service](/services/vision/) with the name `myPeopleDetector`, type `vision` and model `mlmodel`. - Click **Create service**. +In the new vision service panel, configure your service. - ![Create service panel, with the type attribute filled as mlmodel, name attribute filled as people, and model attributed filled as tflite_cpu.](/tutorials/tipsy/app-service-vision-create.png) +From the **Select model** drop-down, select the name of the TFLite model (`people`). - In the new vision service panel, configure your service. - - ![vision service panel called myPeopleDetector with empty Attributes section](/tutorials/tipsy/app-service-vision-before.png) - - Name the ml model name `people`. - - ![vision service panel called myPeopleDetector with filled Attributes section, mlmodel_name is “people”.](/tutorials/tipsy/app-service-vision-after.png) - -## Configure the detection camera +### Configure the detection camera To be able to test that the vision service is working, add a `transform` camera which will add bounding boxes and labels around the objects the service detects. Click the **Components** subtab and click the **Create component** button in the lower-left corner. -Create a [transform camera](/components/camera/transform/) with type `camera` and model `transform`. +Create a [transform camera](/components/camera/transform/) by selecting type `camera` and model `transform`. Name it `detectionCam` and click **Create**. ![detectionCam component panel with type camera and model transform, Attributes section has source and pipeline but they are empty.](/tutorials/tipsy/app-detection-before.png) diff --git a/docs/tutorials/projects/pet-treat-dispenser.md b/docs/tutorials/projects/pet-treat-dispenser.md index ece1a1980f..1656f11488 100644 --- a/docs/tutorials/projects/pet-treat-dispenser.md +++ b/docs/tutorials/projects/pet-treat-dispenser.md @@ -100,20 +100,20 @@ Now that you've set up your robot, you can start configuring and testing it. ### Configure your {{< glossary_tooltip term_id="board" text="board" >}} Head to the **Config** tab on your robot's page. -Click on the **Components** subtab and navigate to the **Create component** menu. +Click on the **Components** subtab and click the **Create component** button in the lower-left corner. Select `board` as the type and `pi` as the model. -Name the component `pi`. +Name the component `pi`, then click **Create**. ![The Viam app showing the configuration page for a board component with name pi.](/tutorials/pet-treat-dispenser/app-board-pi.png) ### Configure your [webcam](/components/camera/webcam/) -Add another component with the type `camera` component and the model `webcam`. -Name the component `petcam`. +Click **Create component** and add your webcam with type `camera` and model `webcam`. +Name the component `petcam`, then click **Create**. Click on the **video path**. -If the robot is connected, a drop down with available cameras will appear. +If the robot is connected, a drop-down menu with available cameras will appear. Select your camera. ![The Viam app showing the configuration page for a camera component with model webcam.](/tutorials/pet-treat-dispenser/app-camera-webcam.png) @@ -124,11 +124,11 @@ If you are unsure which camera to select, selecte one, save the configuration an ### Configure your [stepper motor](/components/motor/gpiostepper/) -Finally, add another component with the type `motor` component and the model `gpiostepper`. +Finally, click **Create component** and add another component with type `motor` and model `gpiostepper`. -1. If you used the same pins as in the wiring diagram, set the `direction` to pin 15 GPIO 22, and the `step` logic to pin 16 GPIO 23. -1. Enable the pin setting as low and configure it to pin 18 GPIO 24. -1. Set the `ticks per rotation` to `400` and select your board model,`pi`. +1. If you used the same pins as in the wiring diagram, set the **direction** to pin `15 GPIO 22`, and the **step** logic to pin `16 GPIO 23`. +1. Set the **Enable pins** toggle to `low`, then set the resulting **Enabled Low** drop-down to pin `18 GPIO 24`. +1. Set the **ticks per rotation** to `400` and select your board model, `pi`. ![The Viam app showing the configuration page for a stepper motor component with model gpiostepper.](/tutorials/pet-treat-dispenser/app-stepper-gpiostepper.png) @@ -298,9 +298,7 @@ Once the model has finished training, deploy it by adding a [ML model service](/ 1. Create a new service, select **ML Model** as the **Type**, and name it `puppymodel`. Select `tflite_cpu` as the **Model**. -![The ML model service panel with the name puppymodel.](/tutorials/pet-treat-dispenser/app-service-mlmodel.png) - -3. To configure your service and deploy a model onto your robot, select **Deploy Model On Robot** for the **Deployment** field. +1. To configure your service and deploy a model onto your robot, select **Deploy Model On Robot** for the **Deployment** field. 1. Select your trained model (`puppymodel`) as your desired **Model**. ### Use the vision service to detect your pet diff --git a/docs/tutorials/projects/send-security-photo.md b/docs/tutorials/projects/send-security-photo.md index 8a588eec3f..2dcb10fb4e 100644 --- a/docs/tutorials/projects/send-security-photo.md +++ b/docs/tutorials/projects/send-security-photo.md @@ -99,14 +99,15 @@ If you want to train your own, you can [train a model](/manage/ml/train-model/). To use the provided Machine Learning model, copy the [effdet0.tflite](https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/effdet0.tflite) file and the [labels.txt](https://github.com/viam-labs/devrel-demos/raw/main/Light%20up%20bot/labels.txt) to your project directory. -Click on the **Services** subtab and navigate to the **Create service** menu. +Click the **Services** subtab. 1. **Configure the ML model service** - Add an [mlmodel](/services/ml/) service with the name `people`, type `mlmodel`, and model `tflite_cpu`. - Click **Create service**. + Add an [mlmodel](/services/ml/) service: - ![Create service panel, with the type attribute filled as mlmodel, name attribute filled as people, and model attribute filled as tflite_cpu.](/tutorials/tipsy/app-service-ml-create.png) + Click **Create service** in the lower-left corner of the **Services** subtab. + Select type `mlmodel`, then select model `tflite_cpu`. + Enter `people` as the name, then click **Create**. In the new ML Model service panel, configure your service. @@ -120,8 +121,6 @@ Click on the **Services** subtab and navigate to the **Create service** menu. Add a [vision service](/services/vision/) with the name `myPeopleDetector`, type `vision` and model `mlmodel`. Click **Create service**. - ![Create service panel, with the type attribute filled as mlmodel, name attribute filled as people, and model attributed filled as tflite_cpu.](/tutorials/tipsy/app-service-vision-create.png) - In the new vision service panel, configure your service. ![vision service panel called myPeopleDetector with empty Attributes section](/tutorials/tipsy/app-service-vision-before.png) diff --git a/docs/tutorials/projects/tipsy.md b/docs/tutorials/projects/tipsy.md index caece880b1..f89aca1ae9 100644 --- a/docs/tutorials/projects/tipsy.md +++ b/docs/tutorials/projects/tipsy.md @@ -76,14 +76,15 @@ Follow the instructions on the **Setup** tab to install `viam-server` on your Ra {{% tab name="Builder UI" %}} Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). -Click on the **Components** subtab and navigate to the **Create component** menu. +Click on the **Components** subtab. -1. **Configure the Pi as a board** +1. **Configure the board** - Add your {{< glossary_tooltip term_id="board" text="board" >}} with the name `local`, type `board`, and model `pi`. - Click **Create component**. + Add a {{< glossary_tooltip term_id="board" text="board component" >}} to represent the Raspberry Pi: - ![Create component panel, with the name attribute filled as local, type attribute filled as board and model attribute filled as Pi.](/tutorials/tipsy/app-board-create.png) + Click the **Create component** button in the lower-left corner of the page. + Select type `board` and model `pi`. + Enter `local` as the name, then click **Create**. You can name your board whatever you want as long as you refer to it by the same name in your code. @@ -93,9 +94,7 @@ Click on the **Components** subtab and navigate to the **Create component** menu Add your right [motor](/components/motor/) with the name `rightMotor`, type `motor`, and model `gpio`. - ![Create component panel, with the name attribute filled as rightMotor, type attribute filled as motor and model attribute filled as gpio.](/tutorials/tipsy/app-motor-create.png) - - After clicking **Create component**, a panel will pop up with empty sections for Attributes, Component Pin Assignment, and other information. + After clicking **Create**, a panel will pop up with empty sections for Attributes, Component Pin Assignment, and other information. ![Alt text: rightMotor component panel with empty sections for Attributes, Component Pin Assignment, and other information.](/tutorials/tipsy/app-motor-attribute.png) @@ -373,30 +372,32 @@ scp labels.txt tipsy@tipsy.local:/home/tipsy/labels.txt {{< tabs >}} {{% tab name="Builder UI" %}} -Click on the **Services** subtab and navigate to the **Create service** menu. +Click on the **Services** subtab. 1. **Configure the ML model service** - Add an [mlmodel](/services/ml/) service with the name `people`, type `mlmodel`, and model `tflite_cpu`. - Click **Create service**. + Add an [mlmodel](/services/ml/) service: - ![Create service panel, with the type attribute filled as mlmodel, name attribute filled as people, and model attribute filled as tflite_cpu.](/tutorials/tipsy/app-service-ml-create.png) + Click **Create service** in the lower-left corner of the page. + Select type `ML Model` and model `TFLite CPU`. + Enter `people` for the name of your service, then click **Create**. In the new ML Model service panel, configure your service. ![mlmodel service panel with empty sections for Model Path, and Optional Settings such as Label Path and Number of threads.](/tutorials/tipsy/app-service-ml-before.png) - Select the **Path to Existing Model On Robot** for the **Deployment** field. - Then specify the absolute **Model Path** as /home/tipsy/effdet0.tflite and any **Optional Settings** such as the absolute **Label Path** as /home/tipsy/labels.txt and the **Number of threads** as 1. + Select the **Path to existing model on robot** for the **Deployment** field. + Then specify the absolute **Model path** as /home/tipsy/effdet0.tflite and any **Optional settings** such as the absolute **Label path** as /home/tipsy/labels.txt and the **Number of threads** as 1. ![mlmodel service panel, Deployment selected as Path to Existing Model On Robot, Model Path filled as /home/tipsy/effdet0.tflite and Label Path filled as /home/tipsy/labels.txt, Number of threads is 1.](/tutorials/tipsy/app-service-ml-after.png) -1. **Configure an mlmodel detector** +1. **Configure an ML model detector** - Add a [vision service](/services/vision/) with the name `myPeopleDetector`, type `vision`, and model `mlmodel`. - Click **Create service**. + Add a [vision service](/services/vision/) detector: - ![Create service panel, with the type attribute filled as mlmodel, name attribute filled as people, and model attributed filled as tflite_cpu.](/tutorials/tipsy/app-service-vision-create.png) + Click **Create service** in the lower-left corner of the page. + Select type `Vision`, then select model `mlmodel`. + Enter `myPeopleDetector` as the name, then click **Create**. In the new vision service panel, configure your service. @@ -408,10 +409,11 @@ Click on the **Services** subtab and navigate to the **Create service** menu. 1. **Configure the detection camera** - To be able to test that the vision service is working, add a `transform` camera which will add bounding boxes and labels around the objects the service detects. + To be able to test that the vision service is working, add a [transform camera](/components/camera/transform/) which will add bounding boxes and labels around the objects the service detects. - Click on the **Components** subtab and navigate to the **Create component** menu. - Create a [transform camera](/components/camera/transform/) with the name `detectionCam`, the type `camera`, and the model `transform`. + Click on the **Components** subtab, then click **Create component** in the lower-left corner of the page. + Select type `camera`, then select model `transform`. + Enter `detectionCam` as the name, then click **Create**. ![detectionCam component panel with type camera and model transform, Attributes section has source and pipeline but they are empty.](/tutorials/tipsy/app-detection-before.png) diff --git a/docs/tutorials/services/accessing-and-moving-robot-arm.md b/docs/tutorials/services/accessing-and-moving-robot-arm.md index 2227ae01e2..0015f7ddc9 100644 --- a/docs/tutorials/services/accessing-and-moving-robot-arm.md +++ b/docs/tutorials/services/accessing-and-moving-robot-arm.md @@ -53,12 +53,12 @@ If you are connecting to a real robotic arm during this tutorial, make sure your 2. Create a new robot. 3. Follow the instructions on the **Setup** tab. 4. Select the **Config** tab. -5. Under the **Components** section, create a component with the following attributes: +5. Under the **Components** subtab, click **Create component** in the lower-left corner and create a component with the following attributes: - * Choose `Arm` as the **Type** selection - * Choose your desired model in the **Model** selection - * If you're using an xArm 6, choose the `xArm6` model from the drop-down list - * Enter `myArm` as the **Name** for this component + * Choose `Arm` as the type. + * Choose your desired model. + * If you're using an xArm 6, choose the `xArm6` model from the drop-down list. + * Enter `myArm` as the **Name** for this component, then click **Create**. 5. In the newly created `myArm` component panel, fill in some additional details: diff --git a/docs/tutorials/services/color-detection-scuttle.md b/docs/tutorials/services/color-detection-scuttle.md index 7ce1bef810..2f3a549859 100644 --- a/docs/tutorials/services/color-detection-scuttle.md +++ b/docs/tutorials/services/color-detection-scuttle.md @@ -48,20 +48,15 @@ Turn on the power to the rover. This tutorial uses the color `#a13b4c` or `rgb(161,59,76)` (a reddish color). +To create a [color detector vision service](/services/vision/detection/): + {{< tabs >}} {{% tab name="Builder" %}} -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. - -Scroll to the **Create Service** section. -To create a [color detector vision service](/services/vision/detection/): - -1. Select `vision` as the **Type**. -2. Enter `my_color_detector` as the **Name**. -3. Select **Color Detector** as the **Model**. -4. Click **Create Service**. +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots). +Click the **Services** subtab and click **Create service** in the lower-left corner. +Select the `Vision` type, then select the `Color Detector` model. +Enter `my_color_detector` as the name for your service and click **Create**. In your vision service's panel, set the following **Attributes**: diff --git a/docs/tutorials/services/try-viam-color-detection.md b/docs/tutorials/services/try-viam-color-detection.md index f5c1c5c27d..0215b41738 100644 --- a/docs/tutorials/services/try-viam-color-detection.md +++ b/docs/tutorials/services/try-viam-color-detection.md @@ -55,20 +55,17 @@ This tutorial uses the color `#7a4f5c` or `rgb(122, 79, 92)` (a reddish color). **Hex color #7a4f5c**: {{}} +Navigate to your robot's **Config** tab on the [Viam app](https://app.viam.com/robots) and configure your [vision service color detector](/services/vision/detection/): + {{< tabs >}} {{% tab name="Builder" %}} -Navigate to the [robot page on the Viam app](https://app.viam.com/robots). -Click on the robot you wish to add the vision service to. -Select the **Config** tab, and click on **Services**. +1. Click the **Services** subtab and click **Create service** in the lower-left corner. + +1. Select the `Vision` type, then select the `ML Model` model. -Scroll to the **Create Service** section. -To create a [vision service](/services/vision/): +1. Enter `my_color_detector` as the name for your detector and click **Create**. -1. Select `Vision` as the **Type**. -1. Enter `my_color_detector` as the **Name**. -1. Select **Color Detector** as the **Model**. -1. Click **Create Service**. 1. In the resulting vision service panel, click the color picker box to set the color to be detected. For this tutorial, set the color to `rgb(122, 79, 92)` or use hex code `#7a4f5c`. diff --git a/docs/tutorials/services/webcam-line-follower-robot.md b/docs/tutorials/services/webcam-line-follower-robot.md index af52fe8a1e..609c963995 100644 --- a/docs/tutorials/services/webcam-line-follower-robot.md +++ b/docs/tutorials/services/webcam-line-follower-robot.md @@ -224,45 +224,47 @@ Now, let's configure the color detector so your rover can detect the line: {{% tab name="Builder UI" %}} Next, navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com). -Click on the **Services** subtab and navigate to the **Create service** menu. +Click on the **Services** subtab. 1. **Add a vision service.** - Next, add a vision service [detector](/services/vision/detection/). - Create an vision service with the name `green_detector`, the type `vision` and the model `color_detector`. - Then click **Create Service**. + Next, add a vision service [detector](/services/vision/detection/): - In your vision service’s panel, select the color your vision service will be detecting, as well as a hue tolerance and a segment size (in pixels). - Use a color picker like [colorpicker.me](https://colorpicker.me/) to approximate the color of your line and get the corresponding rgb or hex value. - We used `rgb(25,255,217)` or `#19FFD9` to match the color of our green electrical tape, and specified a segment size of 100 pixels with a tolerance of 0.06, but you can tweak these later to fine tune your line follower. + Click the **Create service** button in the lower-left corner of the **Services** subtab. + Select type `Vision` and model `Color Detector`. + Enter `green_detector` for the name, then click **Create**. + + In your vision service’s panel, select the color your vision service will be detecting, as well as a hue tolerance and a segment size (in pixels). + Use a color picker like [colorpicker.me](https://colorpicker.me/) to approximate the color of your line and get the corresponding rgb or hex value. + We used `rgb(25,255,217)` or `#19FFD9` to match the color of our green electrical tape, and specified a segment size of 100 pixels with a tolerance of 0.06, but you can tweak these later to fine tune your line follower. 2. Click **Save config** in the bottom left corner of the screen. 3. (optional) **Add a `transform` camera as a visualizer** - If you'd like to see the bounding boxes that the color detector identifies, you'll need to configure a [transform camera](/components/camera/transform/). - This isn't another piece of hardware, but rather a virtual "camera" that takes in the stream from the webcam we just configured and outputs a stream overlaid with bounding boxes representing the color detections. + If you'd like to see the bounding boxes that the color detector identifies, you'll need to configure a [transform camera](/components/camera/transform/). + This isn't another piece of hardware, but rather a virtual "camera" that takes in the stream from the webcam we just configured and outputs a stream overlaid with bounding boxes representing the color detections. - Click on the **Components** subtab and click **Create component**. - Add a [transform camera](/components/camera/transform/) with type `camera` and model `transform`. - Name it `transform_cam` and click **Create**. + Click on the **Components** subtab and click **Create component**. + Add a [transform camera](/components/camera/transform/) with type `camera` and model `transform`. + Name it `transform_cam` and click **Create**. - Replace the attributes JSON object with the following object which specifies the camera source that the `transform` camera will be using and defines a pipeline that adds the defined `detector`: + Replace the attributes JSON object with the following object which specifies the camera source that the `transform` camera will be using and defines a pipeline that adds the defined `detector`: - ```json - { - "source": "my_camera", - "pipeline": [ - { - "type": "detections", - "attributes": { - "detector_name": "green_detector", - "confidence_threshold": 0.6 - } + ```json + { + "source": "my_camera", + "pipeline": [ + { + "type": "detections", + "attributes": { + "detector_name": "green_detector", + "confidence_threshold": 0.6 } - ] - } - ``` + } + ] + } + ``` 4. Click **Save config** in the bottom left corner of the screen. diff --git a/layouts/shortcodes/tabs.html b/layouts/shortcodes/tabs.html index 4882c4b608..e2505add5c 100644 --- a/layouts/shortcodes/tabs.html +++ b/layouts/shortcodes/tabs.html @@ -7,9 +7,9 @@ {{- range $i, $e := $tabs -}} {{- $id := printf "%s-%d" $tab_set_id $i -}} {{- if (eq $i 0) -}} - + {{ else }} - + {{- end -}} {{- end -}} diff --git a/static/include/services/apis/cloud.md b/static/include/services/apis/cloud.md index 11c1df13e4..3d8ec8fa80 100644 --- a/static/include/services/apis/cloud.md +++ b/static/include/services/apis/cloud.md @@ -4,4 +4,13 @@ Method Name | Description [`GetOrganizationNamespaceAvailability`](/program/apis/cloud/#getorganizationnamespaceavailability) | Check the availability of an organization namespace. [`ListOrganizationMembers`](/program/apis/cloud/#listorganizationmembers) | List the members and invites of the current organization. [`UpdateOrganizationInviteAuthorizations`](/program/apis/cloud/#updateorganizationinviteauthorizations) | Update the authorizations attached to an organization invite that has already been created. -[`NewRobot`](/program/apis/cloud/# ) | Create a new robot. +[`CreateLocation`](/program/apis/cloud/#createlocation) | Create and name a location. +[`GetLocation`](/program/apis/cloud/#getlocation) | Get a location by its ID. +[`UpdateLocation`](/program/apis/cloud/#updatelocation ) | Change the name of and/or assign a parent location to a location. +[`DeleteLocation`](/program/apis/cloud/#deletelocation ) | Delete a location. +[`ListLocations`](/program/apis/cloud/#listlocations ) | List locations. +[`LocationAuth`](/program/apis/cloud/#locationauth ) | Get a location's authorization (location secrets). +[`CreateLocationSecret`](/program/apis/cloud/#createlocationsecret ) | Create a new location secret. +[`DeleteLocationSecret`](/program/apis/cloud/#deletelocationsecret ) | Delete a location secret. +[`GetRobot`](/program/apis/cloud/#getrobot ) | Get a robot by robot ID. +[`NewRobot`](/program/apis/cloud/#newrobot ) | Create a new robot. diff --git a/static/js/tabpane-persist.js b/static/js/tabpane-persist.js new file mode 100644 index 0000000000..4ebbac78bb --- /dev/null +++ b/static/js/tabpane-persist.js @@ -0,0 +1,104 @@ +// Utilities +const _tdStoragePersistKey = (tabKey) => + 'td-tp-persist:' + (tabKey || ''); + +const _tdSupportsLocalStorage = () => typeof Storage !== 'undefined'; + +// Helpers +function tdPersistKey(key, value) { + // @requires: tdSupportsLocalStorage(); + console.log("key", key, "value", value); + try { + if (value) { + localStorage.setItem(key, value); + } else { + localStorage.removeItem(key); + } + } catch (error) { + const action = value ? 'add' : 'remove'; + console.error( + `Docsy tabpane: unable to ${action} localStorage key '${key}': `, + error + ); + } +} + +// Retrieve, increment, and store tab-select event count, then returns it. +function tdGetTabSelectEventCountAndInc() { + // @requires: tdSupportsLocalStorage(); + + const storedCount = localStorage.getItem('td-tp-persist-count'); + let numTabSelectEvents = parseInt(storedCount) || 0; + numTabSelectEvents++; + tdPersistKey('td-tp-persist-count', numTabSelectEvents.toString()); + return numTabSelectEvents; +} + +// Main functions + +function tdActivateTabsWithKey(key) { + if (!key) return; + + document.querySelectorAll(`.nav-tabs > .nav-item > a[data-td-tp-persist='${key}']`).forEach((element) => { + new bootstrap.Tab(element).show(); + }); +} + +function tdPersistActiveTab(activeTabKey) { + if (!_tdSupportsLocalStorage()) return; + + tdPersistKey( + _tdStoragePersistKey(activeTabKey), + tdGetTabSelectEventCountAndInc() + ); + tdActivateTabsWithKey(activeTabKey); +} + +// Handlers + +function tdGetAndActivatePersistedTabs(tabs) { + // Get unique persistence keys of tabs in this page + var keyOfTabsInThisPage = [ + ...new Set( + Array.from(tabs).map((el) => el.getAttribute("data-td-tp-persist")) + ), + ]; + + // Create a list of active tabs with their age: + let key_ageList = keyOfTabsInThisPage + // Map to [tab-key, last-activated-age] + .map((k) => [ + k, + parseInt(localStorage.getItem(_tdStoragePersistKey(k))) || 0, + ]) + // Exclude tabs that have never been activated + .filter(([k, v]) => v) + // Sort from oldest selected to most recently selected + .sort((a, b) => a[1] - b[1]); + + // Activate tabs from the oldest to the newest + key_ageList.forEach(([key]) => { + tdActivateTabsWithKey(key); + }); + + return key_ageList; +} + +function tdRegisterTabClickHandler(tabs) { + tabs.forEach((tab) => { + tab.addEventListener('click', () => { + const activeTabKey = tab.getAttribute("data-td-tp-persist"); + tdPersistActiveTab(activeTabKey); + tdActivateTabsWithKey(activeTabKey) + }); + }); +} + +// Register listeners and activate tabs +window.addEventListener('DOMContentLoaded', () => { + if (!_tdSupportsLocalStorage()) return; + + var allTabsInThisPage = document.querySelectorAll(".nav-tabs > .nav-item > a"); + tdRegisterTabClickHandler(allTabsInThisPage); + tdGetAndActivatePersistedTabs(allTabsInThisPage); +}); \ No newline at end of file