diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index dc4014e1cb..a154a8aef0 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -67,16 +67,10 @@ jobs:
uses: actions/download-artifact@v3
with:
name: tutorials-search-file
- - name: Write env
- run: |
- echo TYPESENSE_API_KEY=${{ secrets.TYPESENSE_API_KEY }} > typesense.env
- echo TYPESENSE_HOST=cgnvrk0xwyj9576lp-1.a1.typesense.net >> typesense.env
- echo TYPESENSE_PORT=443 >> typesense.env
- echo TYPESENSE_PROTOCOL=https >> typesense.env
- name: Upload tutorials documents
run: |
jq -c '.[]' typesense.json > documents.jsonl
- curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
+ curl -H "X-TYPESENSE-API-KEY: ${{secrets.TYPESENSE_TUTORIALS_API_KEY}}" \
-X POST \
-T documents.jsonl \
"https://cgnvrk0xwyj9576lp-1.a1.typesense.net/collections/tutorials/documents/import?action=upsert"
diff --git a/assets/components/arm/fake-arm-ui-config.png b/assets/components/arm/fake-arm-ui-config.png
index fcabcc6020..c54f3f66d5 100644
Binary files a/assets/components/arm/fake-arm-ui-config.png and b/assets/components/arm/fake-arm-ui-config.png differ
diff --git a/assets/components/board/upboard-ui-config.png b/assets/components/board/upboard-ui-config.png
index 539ab81d30..511ad8dcd1 100644
Binary files a/assets/components/board/upboard-ui-config.png and b/assets/components/board/upboard-ui-config.png differ
diff --git a/assets/extend/modular-resources/configure/add-module-from-registry.png b/assets/extend/modular-resources/configure/add-module-from-registry.png
new file mode 100644
index 0000000000..3792481cd8
Binary files /dev/null and b/assets/extend/modular-resources/configure/add-module-from-registry.png differ
diff --git a/assets/extend/modular-resources/configure/conf-component-from-module.png b/assets/extend/modular-resources/configure/conf-component-from-module.png
new file mode 100644
index 0000000000..44990a5a82
Binary files /dev/null and b/assets/extend/modular-resources/configure/conf-component-from-module.png differ
diff --git a/assets/extend/modular-resources/configure/conf-module-from-registry.png b/assets/extend/modular-resources/configure/conf-module-from-registry.png
new file mode 100644
index 0000000000..ebd4753672
Binary files /dev/null and b/assets/extend/modular-resources/configure/conf-module-from-registry.png differ
diff --git a/static/js/carousel.js b/assets/js/carousel.js
similarity index 92%
rename from static/js/carousel.js
rename to assets/js/carousel.js
index 78a51e438e..0e9ce894d2 100644
--- a/static/js/carousel.js
+++ b/assets/js/carousel.js
@@ -32,8 +32,10 @@ document.addEventListener('DOMContentLoaded', function() {
});
const scrolllength = carousel.querySelector('ul li:nth-child(2)').offsetLeft - carousel.querySelector('ul li:nth-child(1)').offsetLeft;
const nthchild = (Math.round((ele.scrollLeft/scrolllength)+1));
- carousel.querySelector('ol li:nth-child('+nthchild+')').classList.add('selected');
- carousel.querySelector('ul li:nth-child('+nthchild+')').classList.add('selected');
+ let ol_elem = carousel.querySelector('ol li:nth-child('+nthchild+')');
+ let ul_elem = carousel.querySelector('ul li:nth-child('+nthchild+')');
+ if (ol_elem) { ol_elem.classList.add('selected'); }
+ if (ul_elem) { ul_elem.classList.add('selected'); }
if(carousel.parentElement.parentElement.querySelector('.dynamictitle')) {
const title = carousel.querySelector('ul li:nth-child('+nthchild+') img').getAttribute('title');
if(title) carousel.parentElement.parentElement.querySelector('.dynamictitle').innerHTML = title;
@@ -97,7 +99,7 @@ document.addEventListener('DOMContentLoaded', function() {
}
// Add CSS to hide arrows when all elements visible
- var styles = "@media (min-width:" + (slides.length * 100 + 400) "px) {#board-carousel { padding: 0 !important; }#board-carousel div.prev, #board-carousel div.next {visibility: hidden;}}"
+ var styles = "@media (min-width:" + (slides.length * 100 + 400) + "px) {#board-carousel { padding: 0 !important; }#board-carousel div.prev, #board-carousel div.next {visibility: hidden;}}"
var styleSheet = document.createElement("style")
styleSheet.innerText = styles
diff --git a/static/js/tutorials.js b/assets/js/tutorials.js
similarity index 95%
rename from static/js/tutorials.js
rename to assets/js/tutorials.js
index 1981eba0eb..1e7a6ec194 100644
--- a/static/js/tutorials.js
+++ b/assets/js/tutorials.js
@@ -85,7 +85,7 @@ search.addWidgets([
templates: {
item: `
-
+
{{#webm}}
@@ -213,3 +213,13 @@ search.on('render', function() {
observer.observe()
});
+
+document.body.addEventListener('click', function(event) {
+ let filter_box = document.getElementById('tutorial-filter-items');
+ if (!filter_box.contains(event.target)) {
+ open_elem = filter_box.getElementsByClassName("show");
+ if (open_elem) {
+ open_elem[0].classList.remove("show");
+ }
+ }
+}, true);
\ No newline at end of file
diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss
index 4909d5b9a2..c514a067d4 100644
--- a/assets/scss/_styles_project.scss
+++ b/assets/scss/_styles_project.scss
@@ -1183,10 +1183,20 @@ ul.sectionlist > li:hover {
}
.search-facets {
- width: 100%;
+ width: 540px;
border: 1px solid black;
margin: 0.2rem;
padding: 0.2rem;
+ position: absolute;
+ z-index: 1;
+ background-color: white;
+}
+
+@media (max-width: 800px) {
+.search-facets {
+ max-width: 86%;
+ width: 445px;
+}
}
.search-facets > ul {
@@ -1272,6 +1282,12 @@ a.ais-Pagination-link:hover {
text-align: center;
padding: 0;
}
+
+// Speed up bootstraps transition animations
+.search-facets.collapsing {
+ transition-duration: 0.000002s;
+}
+
// Pagination CSS end
// Tutorials page end
diff --git a/assets/tutorials/blink-an-led/create-component.png b/assets/tutorials/blink-an-led/create-component.png
deleted file mode 100644
index ae8df69cb7..0000000000
Binary files a/assets/tutorials/blink-an-led/create-component.png and /dev/null differ
diff --git a/assets/tutorials/scuttlebot/createcomponent.png b/assets/tutorials/scuttlebot/createcomponent.png
deleted file mode 100644
index 130f3a4f00..0000000000
Binary files a/assets/tutorials/scuttlebot/createcomponent.png and /dev/null differ
diff --git a/assets/tutorials/scuttlebot/scuttle-on-floor-cropped.png b/assets/tutorials/scuttlebot/scuttle-on-floor-cropped.png
new file mode 100644
index 0000000000..9d433a8e91
Binary files /dev/null and b/assets/tutorials/scuttlebot/scuttle-on-floor-cropped.png differ
diff --git a/assets/tutorials/scuttlebot/scuttle-on-floor.png b/assets/tutorials/scuttlebot/scuttle-on-floor.png
new file mode 100644
index 0000000000..d9cf1413e8
Binary files /dev/null and b/assets/tutorials/scuttlebot/scuttle-on-floor.png differ
diff --git a/docs/_index.md b/docs/_index.md
index 85aeb00072..49af563d6f 100644
--- a/docs/_index.md
+++ b/docs/_index.md
@@ -216,5 +216,3 @@ sitemap:
{{< card link="/tutorials/projects/integrating-viam-with-openai/" class="yellow">}}
-
-
diff --git a/docs/components/arm/fake.md b/docs/components/arm/fake.md
index 3787b34080..aea1c28dde 100644
--- a/docs/components/arm/fake.md
+++ b/docs/components/arm/fake.md
@@ -15,10 +15,9 @@ Configure a `fake` arm to test different models of robotic arms without any phys
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your arm, select the type `arm`, and select the `fake` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `fake` model.
+Enter a name for your arm and click **Create**.
![An example configuration for a fake ur5e arm in the Viam app Config Builder.](/components/arm/fake-arm-ui-config.png)
diff --git a/docs/components/arm/ur5e.md b/docs/components/arm/ur5e.md
index 3beb19af7b..78628ff3bd 100644
--- a/docs/components/arm/ur5e.md
+++ b/docs/components/arm/ur5e.md
@@ -14,10 +14,9 @@ Configure a `ur5e` arm to add a [Universal Robots UR5e](https://www.universal-ro
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your arm, select the type `arm`, and select the `ur5e` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `ur5e` model.
+Enter a name for your arm and click **Create**.
![Web UI configuration panel for an arm of model ur5e in the Viam app, with Attributes & Depends On drop-downs and the option to add a frame.](/components/arm/ur5e-ui-config.png)
diff --git a/docs/components/arm/xarm6.md b/docs/components/arm/xarm6.md
index c8e5ef25a8..e9598db784 100644
--- a/docs/components/arm/xarm6.md
+++ b/docs/components/arm/xarm6.md
@@ -15,10 +15,9 @@ Configure an `xArm6` arm to integrate a [UFACTORY xArm 6](https://www.ufactory.c
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your arm, select the type `arm`, and select the `xArm6` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `xArm6` model.
+Enter a name for your arm and click **Create**.
![Web UI configuration panel for an arm of model xArm6 in the Viam app, with Attributes & Depends On drop-downs and the option to add a frame.](/components/arm/xArm6-ui-config.png)
diff --git a/docs/components/arm/xarm7.md b/docs/components/arm/xarm7.md
index 8423bddc65..1e4813b4e1 100644
--- a/docs/components/arm/xarm7.md
+++ b/docs/components/arm/xarm7.md
@@ -15,10 +15,9 @@ Configure an `xArm7` arm to integrate a [UFACTORY xArm 7](https://www.ufactory.c
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your arm, select the type `arm`, and select the `xArm7` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `xArm7` model.
+Enter a name for your arm and click **Create**.
![Web UI configuration panel for an arm of model xArm6 in the Viam app, with Attributes & Depends On drop-downs and the option to add a frame.](/components/arm/xArm7-ui-config.png)
diff --git a/docs/components/arm/xarmlite.md b/docs/components/arm/xarmlite.md
index a5dfa1fbd4..3d48e26dd3 100644
--- a/docs/components/arm/xarmlite.md
+++ b/docs/components/arm/xarmlite.md
@@ -14,10 +14,9 @@ Configure an `xArmLite` arm to add a [UFACTORY Lite 6](https://www.ufactory.cc/p
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your arm, select the type `arm`, and select the `xArmLite` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `xArmLite` model.
+Enter a name for your arm and click **Create**.
![Web UI configuration panel for an arm of model xArmLite in the Viam app, with Attributes & Depends On drop-downs and the option to add a frame.](/components/arm/xArmLite-ui-config.png)
diff --git a/docs/components/arm/yahboom-dofbot.md b/docs/components/arm/yahboom-dofbot.md
index 49bbf4b85a..c2218212f2 100644
--- a/docs/components/arm/yahboom-dofbot.md
+++ b/docs/components/arm/yahboom-dofbot.md
@@ -14,10 +14,9 @@ Configure a `yahboom-dofbot` arm to add a [Yahboom DOFBOT](https://category.yahb
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your arm, select the type `arm`, and select the `yahboom-dofbot` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `yahboom-dofbot` model.
+Enter a name for your arm and click **Create**.
![Web UI configuration panel for an arm of model yahboom-dofbot in the Viam app, with Attributes & Depends On drop-downs and the option to add a frame.](/components/arm/yahboom-dofbot-ui-config.png)
diff --git a/docs/components/base/agilex-limo.md b/docs/components/base/agilex-limo.md
index 923783a61d..82310d8fdb 100644
--- a/docs/components/base/agilex-limo.md
+++ b/docs/components/base/agilex-limo.md
@@ -17,10 +17,9 @@ Configure an `agilex-limo` base as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your base, select the type `base`, and select the `agilex-limo` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `base` type, then select the `agilex-limo` model.
+Enter a name for your base and click **Create**.
![An example configuration for a agilex-limo base in the Viam app Config Builder.](/components/base/agilex-limo-ui-config.png)
diff --git a/docs/components/base/boat.md b/docs/components/base/boat.md
index 2406778c53..270478c593 100644
--- a/docs/components/base/boat.md
+++ b/docs/components/base/boat.md
@@ -17,10 +17,11 @@ To configure a `boat` base as a component of your robot, first configure the [bo
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your base, select the type `base`, and select the `boat` model.
+Click on the **Components** subtab and click **Create component**.
+Select the `base` type, then select the `boat` model.
+Enter a name for your base and click **Create**.
-Click **Create component** and then fill in the attributes for your model:
+Edit and fill in the attributes as applicable.
{{% /tab %}}
{{% tab name="JSON Template" %}}
diff --git a/docs/components/base/fake.md b/docs/components/base/fake.md
index 437e8431aa..21bdf4190f 100644
--- a/docs/components/base/fake.md
+++ b/docs/components/base/fake.md
@@ -17,10 +17,9 @@ Configure a `fake` base as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your base, select the type `base`, and select the `fake` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `base` type, then select the `fake` model.
+Enter a name for your base and click **Create**.
![An example configuration for a fake base in the Viam app Config Builder.](/components/base/fake-base-ui-config.png)
diff --git a/docs/components/base/wheeled.md b/docs/components/base/wheeled.md
index e7a054ff93..e7aa582a9f 100644
--- a/docs/components/base/wheeled.md
+++ b/docs/components/base/wheeled.md
@@ -18,10 +18,9 @@ Configure a `wheeled` base as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your base, select the type `base`, and select the `wheeled` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `base` type, then select the `wheeled` model.
+Enter a name for your arm and click **Create**.
{{< imgproc src="/components/base/wheeled-base-ui-config.png" alt="An example configuration for a wheeled base in the Viam app config builder, with Attributes & Depends On drop-downs and the option to add a frame." resize="600x" >}}
diff --git a/docs/components/board/beaglebone.md b/docs/components/board/beaglebone.md
index 93c7b006f0..e0cc9e53de 100644
--- a/docs/components/board/beaglebone.md
+++ b/docs/components/board/beaglebone.md
@@ -21,10 +21,9 @@ Configure a `beaglebone` board to integrate [BeagleBoard's BeagleBone AI 64](htt
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `beaglebone` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `beaglebone` model.
+Enter a name for your board and click **Create**.
![An example configuration for a beaglebone board in the Viam app Config Builder.](/components/board/beaglebone-ui-config.png)
diff --git a/docs/components/board/fake.md b/docs/components/board/fake.md
index f0cc96ef1a..9de2ac32e3 100644
--- a/docs/components/board/fake.md
+++ b/docs/components/board/fake.md
@@ -15,10 +15,9 @@ Configure a `fake` board to test integrating a board into your robot without phy
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `fake` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `fake` model.
+Enter a name for your board and click **Create**.
![An example configuration for a fake board in the Viam app Config Builder.](/components/board/fake-ui-config.png)
diff --git a/docs/components/board/jetson.md b/docs/components/board/jetson.md
index 9812233b9c..ed8888602a 100644
--- a/docs/components/board/jetson.md
+++ b/docs/components/board/jetson.md
@@ -13,18 +13,25 @@ tags: ["board", "components"]
Follow one of our Jetson [setup guides](/installation/) to prepare your board for running `viam-server` before configuring a `jetson` board.
+If you have a CSI camera, follow [these instructions](/extend/modular-resources/examples/csi/) to configure it using the `viam:camera:csi` model.
+
+{{% /alert %}}
+
+{{% alert title="CAUTION: Use 3.3V inputs and outputs" color="warning" %}}
+
+The jetson's GPIO pins are rated for inputs and outputs at 3.3V. Signals from encoders and sensors at even 5V can cause damage to a pin. We recommend connecting hardware that can operate and send signals at 3.3V or lower. For details, see pages 1-3 of the [Jetson Nano Developer Kit 40-Pin Expansion Header GPIO Usage Considerations Applications Note](https://developer.nvidia.com/jetson-nano-developer-kit-40-pin-expansion-header-gpio-usage-considerations-applications-note)
+
{{% /alert %}}
-Configure a `jetson` board to integrate a [NVIDIA Jetson Orin Module and Developer Kit](https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-orin/), [NVIDIA Jetson Xavier NX](https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-agx-xavier/), or [NVIDIA Jetson Nano](https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-nano/) into your robot:
+Configure a `jetson` board to integrate a [NVIDIA Jetson Orin Module and Developer Kit](https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-orin/), [NVIDIA Jetson AGX](https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-agx-xavier/), or [NVIDIA Jetson Nano](https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/jetson-nano/) into your robot:
{{< tabs name="Configure an jetson Board" >}}
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `jetson` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `jetson` model.
+Enter a name for your board and click **Create**.
![An example configuration for a jetson board in the Viam app Config Builder.](/components/board/jetson-ui-config.png)
diff --git a/docs/components/board/numato.md b/docs/components/board/numato.md
index d462093661..3115f58e65 100644
--- a/docs/components/board/numato.md
+++ b/docs/components/board/numato.md
@@ -16,10 +16,9 @@ Configure a `numato` board to integrate [Numato GPIO Peripheral Modules](https:/
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `numato` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `numato` model.
+Enter a name for your board and click **Create**.
![An example configuration for a numato board in the Viam app Config Builder.](/components/board/numato-ui-config.png)
diff --git a/docs/components/board/pca9685.md b/docs/components/board/pca9685.md
index 9054bd548e..ceec51ee79 100644
--- a/docs/components/board/pca9685.md
+++ b/docs/components/board/pca9685.md
@@ -15,10 +15,9 @@ Configure a `pca9685` board to integrate a [PCA9685 Arduino I2C Inter
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `pca9685` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `pca9685` model.
+Enter a name for your board and click **Create**.
![An example configuration for a pca9685 board in the Viam app Config Builder.](/components/board/pca9685-ui-config.png)
diff --git a/docs/components/board/pi.md b/docs/components/board/pi.md
index 4ee3344f86..aeecf522fe 100644
--- a/docs/components/board/pi.md
+++ b/docs/components/board/pi.md
@@ -21,10 +21,9 @@ Configure a `pi` board to integrate a [Raspberry Pi 4](https://www.raspberrypi.c
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `pi` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `pi` model.
+Enter a name for your board and click **Create**.
![An example board configuration in the app builder UI. The name (local), type (board) and model (pi) are shown. No other attributes are configured.](/tutorials/scuttlebot/board-empty-json.png)
diff --git a/docs/components/board/ti.md b/docs/components/board/ti.md
index 342f81ffb8..27b0901b18 100644
--- a/docs/components/board/ti.md
+++ b/docs/components/board/ti.md
@@ -21,10 +21,9 @@ Configure a `ti` board to integrate a [Texas Instruments TDA4VM](https://devices
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your board, select the type `board`, and select the `ti` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `ti` model.
+Enter a name for your board and click **Create**.
![An example configuration for a ti board in the Viam app Config Builder.](/components/board/ti-ui-config.png)
diff --git a/docs/components/board/upboard.md b/docs/components/board/upboard.md
index 25d2f65b65..86100d6d00 100644
--- a/docs/components/board/upboard.md
+++ b/docs/components/board/upboard.md
@@ -23,20 +23,19 @@ Follow [these instructions](https://ubuntu.com/tutorials/install-ubuntu-server)
Follow [these instructions](https://github.com/up-division/pinctrl-upboard) to do so.
This driver stabilizes the [GPIO pin mapping definition](https://github.com/up-board/up-community/wiki/Pinout) on the board to make it identical to that of a [Raspberry Pi](/components/board/pi/).
-
-{{< tabs name="Configure an upboard Board" >}}
+{{% /tab %}}
{{% tab name="JSON Template" %}}
Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com).
diff --git a/docs/components/camera/_index.md b/docs/components/camera/_index.md
index 341718727e..90dafc6e33 100644
--- a/docs/components/camera/_index.md
+++ b/docs/components/camera/_index.md
@@ -51,6 +51,13 @@ For configuration information, click on one of the following models:
| [`join_pointclouds`](join-pointclouds/) | Combines the point clouds from multiple camera sources and projects them to be from the point of view of target_frame. |
| [`transform`](transform/) | A pipeline for applying transformations to an input image source. |
+Viam also provides the following camera models as [modular resources](/extend/modular-resources/):
+
+| Model | Description |
+| ----- | ----------- |
+| [`viam:lidar:rplidar`](/extend/modular-resources/examples/rplidar/) | A LIDAR scanning device like the [RPlidar A1](https://www.slamtec.com/en/Lidar/A1). |
+| [`viam:camera:csi`](/extend/modular-resources/examples/csi/) | Camera Serial Interface (CSI) cameras, like [these cameras from E-con Systems](https://www.e-consystems.com/nvidia-jetson-agx-orin-cameras.asp) or [this camera from Seed Technologies](https://www.digikey.com/en/products/detail/seeed-technology-co.,-ltd/114992263/12396924). |
+
## Control your camera with Viam's client SDK libraries
To get started using Viam's SDKs to connect to and control your robot, go to your robot's page on [the Viam app](https://app.viam.com), navigate to the **Code sample** tab, select your preferred programming language, and copy the sample code generated.
diff --git a/docs/components/camera/align-color-depth-extrinsics.md b/docs/components/camera/align-color-depth-extrinsics.md
index 4adda5bc3d..01051ab917 100644
--- a/docs/components/camera/align-color-depth-extrinsics.md
+++ b/docs/components/camera/align-color-depth-extrinsics.md
@@ -15,10 +15,9 @@ Use the intrinsics of the color and depth camera, as well as the extrinsic pose
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `align_color_depth_extrinsics` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `align_color_depth_extrinsics` model.
+Enter a name for your camera and click **Create**.
![Configuration of an align color depth extrinsics view in the Viam app config builder.](/components/camera/configure-align-color-depth-extrinsics.png)
diff --git a/docs/components/camera/align-color-depth-homography.md b/docs/components/camera/align-color-depth-homography.md
index 753f442d8a..a1f7ac9a87 100644
--- a/docs/components/camera/align-color-depth-homography.md
+++ b/docs/components/camera/align-color-depth-homography.md
@@ -15,10 +15,9 @@ When you have a depth image and you need it to overlay on top of a color image e
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `align_color_depth_homography` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `align_color_depth_homography` model.
+Enter a name for your camera and click **Create**.
![Configuration of an align color depth homography view in the Viam app config builder.](/components/camera/configure-align-color-depth-homography.png)
diff --git a/docs/components/camera/dual-stream.md b/docs/components/camera/dual-stream.md
index 8a3527eed9..ae8519ff89 100644
--- a/docs/components/camera/dual-stream.md
+++ b/docs/components/camera/dual-stream.md
@@ -16,10 +16,9 @@ One camera server streams a color stream and the other camera server streams a d
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `dual_stream` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `dual_stream` model.
+Enter a name for your camera and click **Create**.
![Configuration of a dual stream camera in the Viam app config builder.](/components/camera/configure-dual-stream.png)
diff --git a/docs/components/camera/fake.md b/docs/components/camera/fake.md
index e3770b4240..546600c48f 100644
--- a/docs/components/camera/fake.md
+++ b/docs/components/camera/fake.md
@@ -19,10 +19,9 @@ You can optionally specify a height and width.
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `fake` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `fake` model.
+Enter a name for your camera and click **Create**.
![Configuration of a fake camera in the Viam app config builder.](/components/camera/configure-fake.png)
diff --git a/docs/components/camera/ffmpeg.md b/docs/components/camera/ffmpeg.md
index a43463467b..a0ceb8d208 100644
--- a/docs/components/camera/ffmpeg.md
+++ b/docs/components/camera/ffmpeg.md
@@ -15,10 +15,9 @@ A `ffmpeg` camera uses a camera, a video file, or a stream as a camera.
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `ffmpeg` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `ffmpeg` model.
+Enter a name for your camera and click **Create**.
![Configuration of a ffmpeg camera in the Viam app config builder.](/components/camera/configure-ffmpeg.png)
diff --git a/docs/components/camera/image-file.md b/docs/components/camera/image-file.md
index 8c8c136e7f..e555a82b72 100644
--- a/docs/components/camera/image-file.md
+++ b/docs/components/camera/image-file.md
@@ -15,10 +15,9 @@ An `image_file` camera gets color and depth image frames or point clouds from a
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `image_file` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `image_file` model.
+Enter a name for your camera and click **Create**.
![Configuration of an image file camera in the Viam app config builder.](/components/camera/configure-image-file.png)
diff --git a/docs/components/camera/join-color-depth.md b/docs/components/camera/join-color-depth.md
index f421776c04..5bd6d3a0ef 100644
--- a/docs/components/camera/join-color-depth.md
+++ b/docs/components/camera/join-color-depth.md
@@ -18,10 +18,9 @@ If you need to adjust the alignment between the depth and color frames, use the
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `join_color_depth` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `join_color_depth` model.
+Enter a name for your camera and click **Create**.
![Configuration of a join color depth view in the Viam app config builder.](/components/camera/configure-join-color-depth.png)
diff --git a/docs/components/camera/join-pointclouds.md b/docs/components/camera/join-pointclouds.md
index c530c26315..3e640a785f 100644
--- a/docs/components/camera/join-pointclouds.md
+++ b/docs/components/camera/join-pointclouds.md
@@ -15,10 +15,9 @@ Combine the point clouds from multiple camera sources and project them to be fro
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `join_pointclouds` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `join_pointclouds` model.
+Enter a name for your camera and click **Create**.
![Configuration of a Join Point Clouds view in the Viam App config builder.](/components/camera/configure-join-pointclouds.png)
diff --git a/docs/components/camera/rtsp.md b/docs/components/camera/rtsp.md
index 057232b494..4da43932a8 100644
--- a/docs/components/camera/rtsp.md
+++ b/docs/components/camera/rtsp.md
@@ -16,10 +16,9 @@ The model doesn’t support streaming cameras with H264/MP4 tracks.
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `rtsp` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `rtsp` model.
+Enter a name for your camera and click **Create**.
![Configuration of a rtsp camera in the Viam app config builder.](/components/camera/configure-rtsp.png)
diff --git a/docs/components/camera/single-stream.md b/docs/components/camera/single-stream.md
index 1bc5c752de..c734ec25de 100644
--- a/docs/components/camera/single-stream.md
+++ b/docs/components/camera/single-stream.md
@@ -25,10 +25,9 @@ Your `single_stream` camera can output:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `single_stream` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `single_stream` model.
+Enter a name for your camera and click **Create**.
![Configuration of a single stream camera in the Viam App config builder.](/components/camera/configure-single-stream.png)
diff --git a/docs/components/camera/transform.md b/docs/components/camera/transform.md
index edad6e2dca..55999a2686 100644
--- a/docs/components/camera/transform.md
+++ b/docs/components/camera/transform.md
@@ -16,10 +16,9 @@ The transformations are applied in the order they are written in the `pipeline`.
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `transform` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `transform` model.
+Enter a name for your camera and click **Create**.
![Configuration of an transform view in the Viam app config builder.](/components/camera/configure-transform.png)
diff --git a/docs/components/camera/velodyne.md b/docs/components/camera/velodyne.md
index 6c14473e79..671153b4be 100644
--- a/docs/components/camera/velodyne.md
+++ b/docs/components/camera/velodyne.md
@@ -16,10 +16,9 @@ The velodyne must be running locally at address `127.0.0.1`.
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `velodyne` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `velodyne` model.
+Enter a name for your camera and click **Create**.
{{< imgproc src="/components/camera/configure-velodyne.png" alt="Configuration of a velodyne camera in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/camera/webcam.md b/docs/components/camera/webcam.md
index cb4e49b03e..9a414b842f 100644
--- a/docs/components/camera/webcam.md
+++ b/docs/components/camera/webcam.md
@@ -16,10 +16,9 @@ If the camera drivers are among those in [this mediadevices repository](https://
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your camera, select the type `camera`, and select the `webcam` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `camera` type, then select the `webcam` model.
+Enter a name for your camera and click **Create**.
{{< imgproc src="/components/camera/configure-webcam.png" alt="Configuration of a webcam camera in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/component/model1.md b/docs/components/component/model1.md
index df53db7386..5dd335d92a 100644
--- a/docs/components/component/model1.md
+++ b/docs/components/component/model1.md
@@ -21,9 +21,13 @@ Click on the **Components** subtab and navigate to the **Create component** menu
Enter a name for your arm, select the `arm` type, and select the `model1` model.
+Click on the **Components** subtab and click **Create component**.
+Select the `arm` type, then select the `model1` model.
+Enter a name for your arm and click **Create**.
+
{{< imgproc src="/components/component/model1-builder.png" alt="Creation of a `model1` arm in the Viam app config builder." resize="600x" >}}
-Click **Create component** and then fill in the attributes for your model.
+Edit and fill in the attributes as applicable.
{{% /tab %}}
{{% tab name="JSON Template" %}}
diff --git a/docs/components/encoder/AMS-AS5048.md b/docs/components/encoder/AMS-AS5048.md
index d6b2cdd9c8..97419b3044 100644
--- a/docs/components/encoder/AMS-AS5048.md
+++ b/docs/components/encoder/AMS-AS5048.md
@@ -21,10 +21,9 @@ To configure the encoder, you must first [configure an I2C bus](/comp
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your encoder, select the type `encoder`, and select the `AMS-AS5048` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `encoder` type, then select the `AMS-AS5048` model.
+Enter a name for your encoder and click **Create**.
![Configuration of an AS5048 encoder in the Viam app config builder.](/components/encoder/configure-am5.png)
diff --git a/docs/components/encoder/arduino.md b/docs/components/encoder/arduino.md
index 8308ca6ca5..306357a852 100644
--- a/docs/components/encoder/arduino.md
+++ b/docs/components/encoder/arduino.md
@@ -13,10 +13,9 @@ draft: true
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your encoder, select the type `encoder`, and select the `arduino` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `encoder` type, then select the `arduino` model.
+Enter a name for your encoder and click **Create**.
![Configuration of an Arduino encoder in the Viam app config builder.](/components/encoder/configure-arduino.png)
diff --git a/docs/components/encoder/fake.md b/docs/components/encoder/fake.md
index b5c7151777..1584625031 100644
--- a/docs/components/encoder/fake.md
+++ b/docs/components/encoder/fake.md
@@ -15,10 +15,9 @@ The `fake` encoder is an encoder model for testing code without any hardware.
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your encoder, select the type `encoder`, and select the `fake` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `encoder` type, then select the `fake` model.
+Enter a name for your encoder and click **Create**.
![Configuration of a fake encoder in the Viam app config builder.](/components/encoder/configure-fake.png)
diff --git a/docs/components/encoder/incremental.md b/docs/components/encoder/incremental.md
index 44842f0f1e..9d14f9b714 100644
--- a/docs/components/encoder/incremental.md
+++ b/docs/components/encoder/incremental.md
@@ -17,10 +17,9 @@ These two pins provide the phase outputs used to measure the speed and direction
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your encoder, select the type `encoder`, and select the `incremental` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `encoder` type, then select the `incremental` model.
+Enter a name for your encoder and click **Create**.
![Configuration of an incremental encoder in the Viam app config builder.](/components/encoder/configure-incremental.png)
diff --git a/docs/components/encoder/single.md b/docs/components/encoder/single.md
index 71a433fd93..7f948420a1 100644
--- a/docs/components/encoder/single.md
+++ b/docs/components/encoder/single.md
@@ -15,10 +15,9 @@ The direction of spin is dictated by the [motor](/components/motor/) that has th
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your encoder, select the type `encoder`, and select the `single` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `encoder` type, then select the `single` model.
+Enter a name for your encoder and click **Create**.
![Configuration of a single encoder in the Viam app config builder.](/components/encoder/configure-single.png)
diff --git a/docs/components/gantry/fake.md b/docs/components/gantry/fake.md
index 5e31f2ef71..cba4e5939a 100644
--- a/docs/components/gantry/fake.md
+++ b/docs/components/gantry/fake.md
@@ -18,10 +18,9 @@ Configure a `fake` gantry as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your gantry, select the type `gantry`, and select the `fake` model.
-
-Click **Create component**:
+Click on the **Components** subtab and click **Create component**.
+Select the `gantry` type, then select the `fake` model.
+Enter a name for your gantry and click **Create**.
![An example configuration for a fake gantry in the Viam app Config Builder.](/components/gantry/fake-gantry-ui-config.png)
diff --git a/docs/components/gantry/multi-axis.md b/docs/components/gantry/multi-axis.md
index b194da7359..46cfcaaf1e 100644
--- a/docs/components/gantry/multi-axis.md
+++ b/docs/components/gantry/multi-axis.md
@@ -17,10 +17,9 @@ Configure a `multi-axis` gantry to integrate a multi-axis gantry into your robot
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your gantry, select the type `gantry`, and select the `multi-axis` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `gantry` type, then select the `multi-axis` model.
+Enter a name for your gantry and click **Create**.
![Creation of a multi-axis gantry component in the Viam app config builder.](/components/gantry/multi-axis-ui-config.png)
diff --git a/docs/components/gantry/single-axis.md b/docs/components/gantry/single-axis.md
index 1b4bceec6e..2dcfcc51d0 100644
--- a/docs/components/gantry/single-axis.md
+++ b/docs/components/gantry/single-axis.md
@@ -17,10 +17,9 @@ Configure a `single-axis` gantry to integrate a single-axis gantry into your rob
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `gantry`, and select the `single-axis` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `gantry` type, then select the `single-axis` model.
+Enter a name for your sensor and click **Create**.
![Creation of a single-axis gantry component in the Viam app config builder.](/components/gantry/single-axis-ui-config.png)
diff --git a/docs/components/gripper/fake.md b/docs/components/gripper/fake.md
index 639e7c62fd..0a7274d000 100644
--- a/docs/components/gripper/fake.md
+++ b/docs/components/gripper/fake.md
@@ -18,10 +18,9 @@ Configure a `fake` gripper as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your gripper, select the type `gripper`, and select the `fake` model.
-
-Click **Create component**:
+Click on the **Components** subtab and click **Create component**.
+Select the `gripper` type, then select the `fake` model.
+Enter a name for your gripper and click **Create**.
![An example configuration for a fake gripper in the Viam app Config Builder.](/components/gripper/fake-gripper-ui-config.png)
diff --git a/docs/components/gripper/softrobotics.md b/docs/components/gripper/softrobotics.md
index d2658a075c..3107f8d4e8 100644
--- a/docs/components/gripper/softrobotics.md
+++ b/docs/components/gripper/softrobotics.md
@@ -13,10 +13,9 @@ The `softrobotics` model supports the [Soft Robotics *m*Grip](https://www.softro
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your gripper, select the type `gripper`, and select the `softrobotics` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `gripper` type, then select the `softrobotics` model.
+Enter a name for your gripper and click **Create**.
![Creation of a softrobotics gripper component in the Viam app config builder.](/components/gripper/softrobotics-ui-config.png)
diff --git a/docs/components/input-controller/fake.md b/docs/components/input-controller/fake.md
index 0eef9a29b0..acd0561f7a 100644
--- a/docs/components/input-controller/fake.md
+++ b/docs/components/input-controller/fake.md
@@ -22,9 +22,9 @@ Refer to the following example configuration for an input controller of model `f
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your input controller, select the type `input_controller`, and select the `fake` model.
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `input_controller` type, then select the `fake` model.
+Enter a name for your input controller and click **Create**.
![An example configuration for a fake input controller component in the Viam App config builder.](/components/input-controller/fake-input-controller-ui-config.png)
diff --git a/docs/components/input-controller/gamepad.md b/docs/components/input-controller/gamepad.md
index 651a697cdf..c9ccad182e 100644
--- a/docs/components/input-controller/gamepad.md
+++ b/docs/components/input-controller/gamepad.md
@@ -20,10 +20,9 @@ Refer to the following example configuration for an input controller of model `g
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your input controller, select the type `input_controller`, and select the `gamepad` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `input_controller` type, then select the `gamepad` model.
+Enter a name for your input controller and click **Create**.
![An example configuration for a linux-based gamepad input controller component in the Viam App config builder](/components/input-controller/gamepad-input-controller-ui-config.png)
diff --git a/docs/components/input-controller/gpio.md b/docs/components/input-controller/gpio.md
index aa15424717..8d93d79270 100644
--- a/docs/components/input-controller/gpio.md
+++ b/docs/components/input-controller/gpio.md
@@ -21,10 +21,9 @@ Be aware that complete configuration is not visible in the "Config Builder" tab:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your input controller, select the type `input_controller`, and select the `gpio` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `input_controller` type, then select the `gpio` model.
+Enter a name for your input controller and click **Create**.
![An example configuration for a GPIO input controller component in the Viam App config builder](/components/input-controller/gpio-input-controller-ui-config.png)
diff --git a/docs/components/input-controller/mux.md b/docs/components/input-controller/mux.md
index 27ec518874..582f1db147 100644
--- a/docs/components/input-controller/mux.md
+++ b/docs/components/input-controller/mux.md
@@ -25,10 +25,9 @@ The following example configuration combines a `gamepad` and a `webgamepad` cont
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your input controller, select the type `input_controller`, and select the `mux` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `input_controller` type, then select the `mux` model.
+Enter a name for your input controller and click **Create**.
![An example configuration for a multiplexed input controller component in the Viam App config builder](/components/input-controller/mux-input-controller-ui-config.png)
diff --git a/docs/components/input-controller/webgamepad.md b/docs/components/input-controller/webgamepad.md
index 4037f3b557..01ddb8c1b0 100644
--- a/docs/components/input-controller/webgamepad.md
+++ b/docs/components/input-controller/webgamepad.md
@@ -24,10 +24,9 @@ Use the following configuration for an input controller of model `webgamepad`:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter the `WebGamepad` name for your input controller, select the type `input_controller`, and select the `webgamepad` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `input_controller` type, then select the `webgamepad` model.
+Enter the name `WebGamepad` and click **Create**.
![An example configuration for a web-based gamepad input controller component in the Viam App config builder](/components/input-controller/webgamepad-input-controller-ui-config.png)
diff --git a/docs/components/motor/28byj48.md b/docs/components/motor/28byj48.md
index 22b46b8e38..01ce9702fe 100644
--- a/docs/components/motor/28byj48.md
+++ b/docs/components/motor/28byj48.md
@@ -25,10 +25,9 @@ Then, add the motor:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `28byj48` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `28byj48` model.
+Enter a name for your motor and click **Create**.
![A 28byj48 motor config.](/components/motor/28byj48-config-ui.png)
diff --git a/docs/components/motor/dmc4000.md b/docs/components/motor/dmc4000.md
index 01aae207fd..c910367a28 100644
--- a/docs/components/motor/dmc4000.md
+++ b/docs/components/motor/dmc4000.md
@@ -20,10 +20,9 @@ You can drive other types of motors with Viam and the DMC-40x0 controller by [cr
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `DMC4000` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `DMC4000` model.
+Enter a name for your motor and click **Create**.
![A DMC4000 motor config with the attributes configured per the Raw JSON on the next tab in this doc.](/components/motor/dmc4000-config-ui.png)
diff --git a/docs/components/motor/fake.md b/docs/components/motor/fake.md
index 2cfcb73183..35955cafb9 100644
--- a/docs/components/motor/fake.md
+++ b/docs/components/motor/fake.md
@@ -15,10 +15,9 @@ For example, you can use a `fake` component as a placeholder while waiting on a
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `fake` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `fake` model.
+Enter a name for your motor and click **Create**.
![A fake motor config.](/components/motor/fake-config-ui.png)
diff --git a/docs/components/motor/gpio/_index.md b/docs/components/motor/gpio/_index.md
index a79ed786d5..e3dedd9e17 100644
--- a/docs/components/motor/gpio/_index.md
+++ b/docs/components/motor/gpio/_index.md
@@ -20,10 +20,9 @@ Then add your motor:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `gpio` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `gpio` model.
+Enter a name for your motor and click **Create**.
![G P I O motor config in the builder UI with the In1 and In2 pins configured and the PWM pin field left blank.](/components/motor/gpio-config-ui.png)
diff --git a/docs/components/motor/gpiostepper.md b/docs/components/motor/gpiostepper.md
index bbef05d009..39ff50161d 100644
--- a/docs/components/motor/gpiostepper.md
+++ b/docs/components/motor/gpiostepper.md
@@ -21,10 +21,9 @@ Then, add the motor:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `gpiostepper` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `gpiostepper` model.
+Enter a name for your motor and click **Create**.
![Screenshot of a gpiostepper motor config with the step and dir pins configured to pins 13 and 15.](/components/motor/gpiostepper-config-ui.png)
diff --git a/docs/components/motor/roboclaw.md b/docs/components/motor/roboclaw.md
index 411b09e160..9b828be133 100644
--- a/docs/components/motor/roboclaw.md
+++ b/docs/components/motor/roboclaw.md
@@ -25,10 +25,9 @@ To configure a `roboclaw` motor as a component of your robot:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `roboclaw` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `roboclaw` model.
+Enter a name for your motor and click **Create**.
![A roboclaw motor config.](/components/motor/roboclaw-ui-config.png)
diff --git a/docs/components/motor/tmc5072.md b/docs/components/motor/tmc5072.md
index 5a83c360ea..f6e3432c14 100644
--- a/docs/components/motor/tmc5072.md
+++ b/docs/components/motor/tmc5072.md
@@ -19,10 +19,9 @@ Then, add the motor:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your motor, select the type `motor`, and select the `TMC5072` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `motor` type, then select the `TMC5072` model.
+Enter a name for your motor and click **Create**.
![Config panel for a TMC5072 motor with attributes filled in according to the Raw JSON tab.](/components/motor/tmc5072-config-ui.png)
diff --git a/docs/components/movement-sensor/_index.md b/docs/components/movement-sensor/_index.md
index e86223619d..8a06c78fc0 100644
--- a/docs/components/movement-sensor/_index.md
+++ b/docs/components/movement-sensor/_index.md
@@ -38,6 +38,7 @@ Model | Description
[`accel-adxl345`](./adxl345/) | The [Analog Devices ADXL345](https://www.analog.com/en/products/adxl345.html) digital accelerometer
[`gyro-mpu6050`](./mpu6050/) | A gyroscope/accelerometer manufactured by TDK InvenSense
[`merged`](./merged/) | A model that allows you to aggregate the API methods supported by multiple sensors into a singular sensor client, effectively merging the models of the individual resources
+[`wheeled-odometry`](./wheeled-odometry/) | A model that uses [encoders](/components/encoder/) to get an odometry estimate from a wheeled base
[`fake`](./fake/) | Used to test code without hardware
## Control your movement sensor with Viam's client SDK libraries
diff --git a/docs/components/movement-sensor/cameramono.md b/docs/components/movement-sensor/cameramono.md
index 884036698f..173f931f69 100644
--- a/docs/components/movement-sensor/cameramono.md
+++ b/docs/components/movement-sensor/cameramono.md
@@ -24,10 +24,9 @@ The `camera_mono` model can use any single [camera](/components/camera/) within
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `camera_mono` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `camera_mono` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/camera-mono-builder.png" alt="Creation of an `camera_mono` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/fake.md b/docs/components/movement-sensor/fake.md
index 17f3ed50ee..d5797fc432 100644
--- a/docs/components/movement-sensor/fake.md
+++ b/docs/components/movement-sensor/fake.md
@@ -17,10 +17,9 @@ Note that this model does not get any actual readings, so it supports these meth
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `fake` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `fake` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/fake-builder.png" alt="Creation of an `fake` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/gps/gps-nmea-rtk-pmtk.md b/docs/components/movement-sensor/gps/gps-nmea-rtk-pmtk.md
index dd536e1a39..812953a3df 100644
--- a/docs/components/movement-sensor/gps/gps-nmea-rtk-pmtk.md
+++ b/docs/components/movement-sensor/gps/gps-nmea-rtk-pmtk.md
@@ -35,10 +35,9 @@ If your movement sensor uses serial communication instead of I
2C, use
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `gps-nmea-rtk-pmtk` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `gps-nmea-rtk-pmtk` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/gps-nmea-rtk-pmtk-builder.png" alt="Creation of a `gps-nmea-rtk-pmtk` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/gps/gps-nmea-rtk-serial.md b/docs/components/movement-sensor/gps/gps-nmea-rtk-serial.md
index fe89be6498..b194c52f56 100644
--- a/docs/components/movement-sensor/gps/gps-nmea-rtk-serial.md
+++ b/docs/components/movement-sensor/gps/gps-nmea-rtk-serial.md
@@ -38,10 +38,9 @@ If your movement sensor uses I
2C communication instead of serial, use
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `gps-nmea-rtk-serial` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `gps-nmea-rtk-serial` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/gps-nmea-rtk-serial-builder.png" alt="Creation of a `gps-nmea-rtk-serial` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/gps/gps-nmea.md b/docs/components/movement-sensor/gps/gps-nmea.md
index d9b3257c38..dd4496668e 100644
--- a/docs/components/movement-sensor/gps/gps-nmea.md
+++ b/docs/components/movement-sensor/gps/gps-nmea.md
@@ -21,10 +21,9 @@ The `gps-nmea` model can be connected using USB and send data through a serial c
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `gps-nmea` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `gps-nmea` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/gps-nmea-builder.png" alt="Creation of a `gps-nmea` movement sensor in the Viam app config builder." resize="600x" >}}
@@ -127,13 +126,14 @@ You can use either serial communication (over USB) or I
2C communicati
Use `connection_type` to specify `"serial"` or `"I2C"` connection in the main `attributes` config.
Then create a struct within `attributes` for either `serial_attributes` or `i2c_attributes`, respectively.
+See examples of this struct in the example tabs above.
{{< tabs >}}
{{% tab name="Serial" %}}
### Serial Config Attributes
-For a movement sensor communicating over serial, you'll need to include a `serial_attributes` field containing:
+For a movement sensor communicating over serial, you'll need to include a `serial_attributes` struct containing:
Name | Type | Inclusion | Description
---- | ---- | --------- | -----------
@@ -145,7 +145,7 @@ Name | Type | Inclusion | Description
### I2C Config Attributes
-For a movement sensor communicating over I
2C, you'll need a `i2c_attributes` field containing:
+For a movement sensor communicating over I
2C, you'll need a `i2c_attributes` struct containing:
Name | Type | Inclusion | Description
---- | ---- | --------- | -----------
diff --git a/docs/components/movement-sensor/imu/imu-vectornav.md b/docs/components/movement-sensor/imu/imu-vectornav.md
index ea69508c40..500b46af55 100644
--- a/docs/components/movement-sensor/imu/imu-vectornav.md
+++ b/docs/components/movement-sensor/imu/imu-vectornav.md
@@ -17,10 +17,9 @@ The `imu-vectornav` movement sensor model supports IMUs manufactured by [VectorN
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `imu-vectornav` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `imu-vectornav` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/imu-vectornav-builder.png" alt="Creation of an `imu-vectornav` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/imu/imu-wit.md b/docs/components/movement-sensor/imu/imu-wit.md
index 2aeb3eb357..d7525d8c51 100644
--- a/docs/components/movement-sensor/imu/imu-wit.md
+++ b/docs/components/movement-sensor/imu/imu-wit.md
@@ -27,10 +27,9 @@ Other WitMotion IMUs that communicate over serial may also work with this model
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `imu-wit` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `imu-wit` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/imu-wit-builder.png" alt="Creation of an `imu-wit` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/merged.md b/docs/components/movement-sensor/merged.md
index fdf6f27267..496d5f67e9 100644
--- a/docs/components/movement-sensor/merged.md
+++ b/docs/components/movement-sensor/merged.md
@@ -24,10 +24,9 @@ Reference the `name` you configure for each individual component in the `merged`
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `merged` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `merged` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/merged-config-builder.png" alt="Creation of an `merged` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/mpu6050.md b/docs/components/movement-sensor/mpu6050.md
index 2c17a9d727..83122827fc 100644
--- a/docs/components/movement-sensor/mpu6050.md
+++ b/docs/components/movement-sensor/mpu6050.md
@@ -14,10 +14,9 @@ The `gyro-mpu6050` movement sensor model supports a combination [gyroscope and a
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your movement sensor, select the `movement-sensor` type, and select the `gyro-mpu6050` model.
-
-Click **Create Component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `movement-sensor` type, then select the `gyro-mpu6050` model.
+Enter a name for your movement sensor and click **Create**.
{{< imgproc src="/components/movement-sensor/mpu6050-builder.png" alt="Creation of an `gyro-mpu6050` movement sensor in the Viam app config builder." resize="600x" >}}
diff --git a/docs/components/movement-sensor/wheeled-odometry.md b/docs/components/movement-sensor/wheeled-odometry.md
new file mode 100644
index 0000000000..0e7d40f571
--- /dev/null
+++ b/docs/components/movement-sensor/wheeled-odometry.md
@@ -0,0 +1,64 @@
+---
+title: "Configure a wheeled-odometry movement sensor"
+linkTitle: "wheeled-odometry"
+type: "docs"
+description: "Configure a wheeled-odometry movement sensor."
+images: ["/icons/components/imu.svg"]
+tags: ["movement sensor", "components", "encoder", "motor", "base", "wheeled", "odometry"]
+# SMEs: Rand, Martha
+---
+
+Configure a `wheeled-odometry` movement sensor to implement _wheeled odometry_ on your robot.
+
+_Wheeled odometry_ is the estimation of the rate of change of position, orientation, linear velocity, and angular velocity using the dimensions of a base, calculated by measuring the movement of the motors through encoders.
+Because of this method of estimation, you don't have to have a specific piece of movement sensor hardware to implement `wheeled-odometry` on your robot.
+This model uses [encoders](/components/encoder/) from [position reporting motors](/components/motor/) to get an odometry estimate of a wheeled base as it moves.
+
+With a configured `wheeled-odometry` movement sensor, your robot calculates an estimation of the position, orientation, linear velocity, and angular velocity of the wheeled base each time `time_interval_msec` elapses during a [session](/program/apis/sessions/).
+You can access these readings through the [movement sensor API](/components/movement-sensor/#api).
+For the best accuracy with odometry calculations, it is recommended you configure a time interval of less than `1000` milliseconds.
+
+After configuring a `wheeled-odometry` movement sensor, you can operate your base with Viam's built-in services like the [navigation service](/services/navigation/).
+
+## Set-up requirements
+
+To prepare your robot, attach [encoders](/components/encoder/) to each of the position-reporting motors on your base to measure their rotation.
+
+- Select motors that can report their own position, like an encoded [`roboclaw`](/components/motor/roboclaw/) or [`gpio` motors](/components/motor/gpio/) with [encoders](/components/encoder/#configuration), or the [`odrive`](/extend/modular-resources/examples/odrive/) module.
+You can access this property of a configured motor through the [motor API's `GetProperties()`](/components/motor/#getproperties).
+- Configure your rover as a [wheeled base component](/components/base/wheeled/).
+Make sure to configure the base width and circumference, as these measurements as a property of the base are vital for accurate odometry estimations by your movement sensor. This movement sensor accesses these values through the base's `GetProperties()` API method.
+- Configure each of the position-reporting motors [as motor components](/components/motor/).
+- Then, proceed to [configure](#configuration) a `wheeled-odometry` movement sensor with the name of each of the motor components.
+
+## Configuration
+
+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.
+Select **Raw JSON** mode.
+Copy and paste the following:
+
+```json {class="line-numbers linkable-line-numbers"}
+"name" : "
",
+"type" : "movement_sensor",
+"model" : "wheeled-odometry",
+"attributes" : {
+ "base" : "",
+ "left_motors" : ["", ""],
+ "right_motors" : [""],
+ "time-interval-msec":
+}
+```
+
+Fill in and edit the attributes as applicable.
+
+## Attributes
+
+The following attributes are available for `wheeled-odometry` movement sensors:
+
+| Name | Type | Inclusion | Description |
+| ---- | ---- | --------- | ----------- |
+| `base` | string | **Required** | The `name` of the [base](/components/base/) to which the encoders making up this movement sensor are wired. |
+| `left_motors` | object | **Required** | A list containing the name of each of the bases' left [position-reporting motors](/components/motor/gpio/). |
+| `right_motors` | object | **Required** | A list containing the name of each of the bases' right [position-reporting motors](/components/motor/gpio/). |
+| `time_interval_msec` | number | Optional | The time in milliseconds between each wheeled odometry calculation.
Default: `500.0` |
diff --git a/docs/components/sensor/bme280.md b/docs/components/sensor/bme280.md
index a0a25ba0e2..cea9299084 100644
--- a/docs/components/sensor/bme280.md
+++ b/docs/components/sensor/bme280.md
@@ -16,10 +16,9 @@ Configure a `bme280` sensor to integrate a [BME280 environmental sensor](https:/
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `bme280` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `bme280` model.
+Enter a name for your sensor and click **Create**.
![Creation of a bme280 sensor in the Viam app config builder.](/components/sensor/bme280-sensor-ui-config.png)
diff --git a/docs/components/sensor/ds18b20.md b/docs/components/sensor/ds18b20.md
index 49a42abd0a..da6bc7dffe 100644
--- a/docs/components/sensor/ds18b20.md
+++ b/docs/components/sensor/ds18b20.md
@@ -16,10 +16,9 @@ Configure a `ds18b20` sensor to integrate a [DallasTemperature DS18B20 1-wire di
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `ds18b20` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `ds18b20` model.
+Enter a name for your sensor and click **Create**.
![Creation of a ds18b20 sensor in the Viam app config builder.](/components/sensor/ds18b20-sensor-ui-config.png)
diff --git a/docs/components/sensor/fake.md b/docs/components/sensor/fake.md
index 8bba8ce805..fdba3cec96 100644
--- a/docs/components/sensor/fake.md
+++ b/docs/components/sensor/fake.md
@@ -18,9 +18,9 @@ Configure a `fake` sensor as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `fake` model.
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `fake` model.
+Enter a name for your sensor and click **Create**.
![An example configuration for a fake sensor in the Viam app Config Builder. Attributes are left blank.](/components/sensor/fake-sensor-ui-config.png)
diff --git a/docs/components/sensor/power_ina219.md b/docs/components/sensor/power_ina219.md
index 697dc73f4f..58a7e13ba7 100644
--- a/docs/components/sensor/power_ina219.md
+++ b/docs/components/sensor/power_ina219.md
@@ -17,10 +17,9 @@ Configure a `power_ina219` sensor to integrate a [INA219 current sensor](https:/
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `power_ina219` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `power_ina219` model.
+Enter a name for your sensor and click **Create**.
![Creation of a power_ina219 sensor in the Viam app config builder.](/components/sensor/power-ina219-sensor-ui-config.png)
diff --git a/docs/components/sensor/renogy.md b/docs/components/sensor/renogy.md
index a251db6a8c..1abf644c18 100644
--- a/docs/components/sensor/renogy.md
+++ b/docs/components/sensor/renogy.md
@@ -16,10 +16,9 @@ Configure a `renogy` sensor to integrate a [Renogy battery temperature sensor](h
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `renogy` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `renogy` model.
+Enter a name for your sensor and click **Create**.
![Creation of a renogy sensor in the Viam app config builder.](/components/sensor/renogy-sensor-ui-config.png)
diff --git a/docs/components/sensor/sensirion-sht3xd.md b/docs/components/sensor/sensirion-sht3xd.md
index e3cb514e5b..0a721bca96 100644
--- a/docs/components/sensor/sensirion-sht3xd.md
+++ b/docs/components/sensor/sensirion-sht3xd.md
@@ -16,10 +16,9 @@ Configure a `sensirion-sht3xd` sensor to integrate a [Sensirion SHT3x-DIS temper
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `sensirion-sht3xd` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `sensirion-sht3xd` model.
+Enter a name for your sensor and click **Create**.
![Creation of a sensirion-sht3xd sensor in the Viam app config builder.](/components/sensor/sensirion-sht3xd-sensor-ui-config.png)
diff --git a/docs/components/sensor/ultrasonic.md b/docs/components/sensor/ultrasonic.md
index 4bd377b64f..f5a8f183ce 100644
--- a/docs/components/sensor/ultrasonic.md
+++ b/docs/components/sensor/ultrasonic.md
@@ -16,10 +16,9 @@ Configure an `ultrasonic` sensor to integrate an [HC-S204 ultrasonic distance se
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your sensor, select the type `sensor`, and select the `ultrasonic` model.
-
-Click **Create component**.
+Click on the **Components** subtab and click **Create component**.
+Select the `sensor` type, then select the `ultrasonic` model.
+Enter a name for your sensor and click **Create**.
![Creation of a ultrasonic sensor in the Viam app config builder.](/components/sensor/ultrasonic-sensor-ui-config.png)
diff --git a/docs/components/servo/fake.md b/docs/components/servo/fake.md
index 75d49f8c8f..124b717d96 100644
--- a/docs/components/servo/fake.md
+++ b/docs/components/servo/fake.md
@@ -17,10 +17,9 @@ Configure a `fake` servo as follows:
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your servo, select the type `servo`, and select the `fake` model.
-
-Click **Create component**:
+Click on the **Components** subtab and click **Create component**.
+Select the `servo` type, then select the `fake` model.
+Enter a name for your servo and click **Create**.
![An example configuration for a fake servo in the Viam app Config Builder.](/components/servo/fake-servo-ui-config.png)
diff --git a/docs/components/servo/gpio.md b/docs/components/servo/gpio.md
index 57a096e214..9a43d765a9 100644
--- a/docs/components/servo/gpio.md
+++ b/docs/components/servo/gpio.md
@@ -15,10 +15,9 @@ Configure a `gpio` servo to integrate a hobby servo controlled by general-purpos
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your servo, select the type `servo`, and select the `gpio` model.
-
-Click **Create component**:
+Click on the **Components** subtab and click **Create component**.
+Select the `servo` type, then select the `gpio` model.
+Enter a name for your servo and click **Create**.
![An example configuration for a gpio servo in the Viam app Config Builder.](/components/servo/gpio-servo-ui-config.png)
diff --git a/docs/components/servo/pi.md b/docs/components/servo/pi.md
index 8d7221e04a..6e15b6d8c1 100644
--- a/docs/components/servo/pi.md
+++ b/docs/components/servo/pi.md
@@ -21,10 +21,9 @@ Configure a `pi` servo to integrate a hobby servo controlled by general-purpose
{{% 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 **Components** subtab and navigate to the **Create component** menu.
-Enter a name for your servo, select the type `servo`, and select the `pi` model.
-
-Click **Create component**:
+Click on the **Components** subtab and click **Create component**.
+Select the `servo` type, then select the `pi` model.
+Enter a name for your servo and click **Create**.
{{< imgproc src="/components/servo/pi-servo-ui-config.png" alt="An example configuration for a pi servo in the Viam app Config Builder." resize="600x" >}}
diff --git a/docs/extend/_index.md b/docs/extend/_index.md
index 2e68bdc505..d5c618c8ab 100644
--- a/docs/extend/_index.md
+++ b/docs/extend/_index.md
@@ -1,26 +1,24 @@
---
-title: "Extend Viam with custom resources"
+title: "Extend Viam with modular resources"
linkTitle: "Extend Viam"
weight: 63
simple_list: true
no_list: true
type: docs
tags: ["server", "rdk", "extending viam", "modular resources", "components", "services"]
-description: "Use the SDKs to extend Viam with custom components and services."
+description: "Extend Viam with modular resources from the Viam Registry."
aliases:
- "/program/extend/"
---
Viam's [Robot Development Kit (RDK)](/internals/rdk/) provides built-in support for a variety of {{< glossary_tooltip term_id="resource" text="resources" >}}:
-- Various types and models of hardware [components](/components/).
+- Various types of hardware [components](/components/).
- High-level functionality exposed as [services](/services/).
-However, you may want to use a hardware component to build your robot that is not built-in to the RDK.
-Alternatively, you might want to add new functionality to an existing model of component or create a custom service for your robot to use.
-You can extend Viam in these and other ways by creating and using custom resources.
+However, if you want to work with a new hardware component that is not already supported by Viam, or want to introduce a new software service or service model to support additional functionality on your robot, you can extend Viam by adding a {{< glossary_tooltip term_id="module" text="modular resource" >}} to your robot.
-Click on the cards below for instructions on implementing custom resources through {{< glossary_tooltip term_id="module" text="modules" >}} or {{< glossary_tooltip term_id="remote" text="remotes" >}}:
+Click on the cards below for instructions on implementing modular resources through {{< glossary_tooltip term_id="module" text="modules" >}} or {{< glossary_tooltip term_id="remote" text="remotes" >}}:
{{< cards >}}
{{% card link="/extend/modular-resources" %}}
diff --git a/docs/extend/modular-resources/_index.md b/docs/extend/modular-resources/_index.md
index 4c02378e0c..97e28d9249 100644
--- a/docs/extend/modular-resources/_index.md
+++ b/docs/extend/modular-resources/_index.md
@@ -4,31 +4,70 @@ linkTitle: "Modular Resources"
weight: 10
type: "docs"
tags: ["server", "rdk", "extending viam", "modular resources", "components", "services"]
-description: "Use the Viam module system to implement custom resources that can be included in any Viam-powered robot."
+description: "Use the Viam module system to implement modular resources that can be included in any Viam-powered robot."
no_list: true
aliases:
- "/program/extend/modular-resources/"
---
-The Viam module system allows you to integrate custom {{< glossary_tooltip term_id="resource" text="resources" >}} into any robot running on Viam.
-`viam-server` [manages](/extend/modular-resources/key-concepts/) modular resources and built-in resources in the same way.
+At Viam, a robot is configured with one or more {{< glossary_tooltip term_id="resource" text="resources" >}} ([components](/components/) or [services](/services/)) which are each defined by a [public API](/extend/modular-resources/key-concepts/#valid-apis-to-implement-in-your-model).
+While Viam offers a number of built-in implementations against these APIs, such as the [wheeled base](/components/base/wheeled/), you may also write your own implementations in order to extend the capabilities of your robot.
-Modular resources can be:
+For example, you can:
-1. New models of built-in [components](/components/) or [services](/services/) that implement the built-in resource {{< glossary_tooltip term_id="subtype" text="subtype" >}}'s API through Viam's [client SDKs](/program/apis/).
-2. Brand new types of resources that define their own API in [protocol buffers](https://developers.google.com/protocol-buffers).
+- **Implement a custom component:** If your robot has specialty hardware, such as an unsupported [motor](/components/motor/), and you want to control it using Viam, you can write a driver to support your hardware by implementing the corresponding component API.
+
+- **Implement a custom service:** If your robot makes use of a specialty algorithm or data model when working with services such as [SLAM](/services/slam/), [Vision](/services/vision/), or [Motion planning](/services/motion/), you can implement your own algorithm or model against the corresponding service API.
+
+- **Implement fully custom logic:** If your robot runs specialty or proprietary logic, and you want to use Viam to manage and control that logic, such as when managing a software development lifecyle, you can implement your own custom logic by wrapping the generic API.
+
+These custom implementations are called {{< glossary_tooltip term_id="module" text="modular resources" >}}, and are made available for use on a robot through [modules](/extend/modular-resources/key-concepts/#modules).
+A module can provide one or more modular resources, and can be added to your robot from the Viam Registry.
+
+## The Viam Registry
+
+The [Viam Registry](https://app.viam.com/registry) allows hardware and software engineers to collaborate on their robotics projects by writing and sharing custom modules with each other.
+You can add a module from the Viam Registry directly from your robot's **Configuration** tab in [the Viam app](https://app.viam.com/), using the **+ Create component** button.
+
+The code behind any modular resource can be packaged as a [module](/extend/modular-resources/key-concepts/#modules) and uploaded to the Viam Registry.
+Once the module has been uploaded to the Registry, you can [deploy the module](/extend/modular-resources/configure/) to any robot in your organization from [the Viam app](https://app.viam.com/).
+
+### 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/)).
+
+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.
+Public modules also display the number of times a module has been deployed to a robot.
+
+When you make changes to your module, you can [uploaded the newer version](/extend/modular-resources/upload/#update-an-existing-module) with a new version number, and the Viam Registry will track each version that you upload.
+
+### Deploying to a Robot
+
+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/).
+
+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.
## Get Started
-To get started adding custom resources to your robot, learn the [key concepts](/extend/modular-resources/key-concepts/) behind Viam's resource APIs that make the module system possible.
+To get started working with modular resources:
+
+- Learn the [key concepts](/extend/modular-resources/key-concepts/) behind Viam's modular resources that make the module system possible.
+
+- [Create your own module](/extend/modular-resources/create/) implementing at least one modular resource.
+
+- [Upload your module to the Viam Registry](/extend/modular-resources/upload/) to share with the community, or just to your own organization.
-- To create your own module and modular resources, follow [these instructions](/extend/modular-resources/create/).
+- Browse [the Viam Registry](https://app.viam.com/registry) to see modules uploaded by other users.
-- To download modules and add modular resources that other users have built to your robot, follow one of Viam's [module setup guides](/extend/modular-resources/examples/).
+- [Deploy a module](/extend/modular-resources/configure/) to your robot from the Registry.
-- To configure a module and modular resource, follow [these instructions](/extend/modular-resources/configure/).
+- Browse the [modular resources tutorials](/extend/modular-resources/examples/) for examples of deploying and using custom modular resources on your robot.
-Once you have configured a modular resource, you can test the custom resource using the [Control tab](/manage/fleet/#remote-control) and [program](/program/) it with Viam's Go or Python SDKs.
+Once you have deployed a modular resource, you can test the custom resource using the [Control tab](/manage/fleet/#remote-control) and [program](/program/) it with Viam's Go or Python SDKs.
## Related tutorials
diff --git a/docs/extend/modular-resources/configure.md b/docs/extend/modular-resources/configure.md
index c3975ec043..4ead43ea07 100644
--- a/docs/extend/modular-resources/configure.md
+++ b/docs/extend/modular-resources/configure.md
@@ -1,30 +1,170 @@
---
-title: "Configure your module and modular resource"
+title: "Configure a module on your robot"
linkTitle: "Configure"
weight: 30
type: "docs"
tags: ["server", "rdk", "extending viam", "modular resources", "components", "services"]
-description: "Use the Viam module system to implement custom resources that can be included in any Viam-powered robot."
+description: "Add and configure a module from the Viam Registry on your robot."
no_list: true
---
-Configure a module on your robot to make one or more modular resources available for configuration.
+You can extend Viam by adding a module on your robot to make one or more modular resources available for configuration.
+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).
-If you are developing your own modular resource, you must 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).
+A *module* makes one or more *modular resources* available for configuration.
+See [Key Concepts of Modular Resource APIs](/extend/modular-resources/key-concepts/) for more information.
-Follow these steps to configure the module and modular resource:
+## Add a module from the Viam Registry
-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 custom resource provided by the configured **module** to the configuration of your robot.
+The Viam Registry is a central repository of modules from both Viam and the robotics community that allows you to easily extend Viam's capabilities on your robot.
+
+To add a module from the Viam Registry to your robot:
+
+1. Navigate to the **Config** tab of your robot's page in [the Viam app](https://app.viam.com).
+1. Click on the **Components** subtab and click the **Create component** button.
+1. Enter the name of the module you would like to add to your robot.
+ To find the name of a module you're interested in, you can:
+
+ - Start typing to search for modules by name.
+ Modules available from the Viam Registry will be listed under the `From Registry` section of the search results.
+ - [Browse the Viam Registry](https://app.viam.com/modules) directly to search available modules.
+
+ {{}}
+
+1. After entering the name of the module that you would like to add to your robot, select the matching module in the search results and click the **Add module** button.
+
+When you add a module from the Viam Registry, the custom modular component it provides appears under the **Components** subtab like any other component.
+You can also find [the module itself](#configure-a-module-from-the-viam-registry) listed as **Deployed** under the **Modules** subtab.
+
+{{}}
+
+If the module requires you to configure specific **Atrributes**, click the **URL** link in the module's configuration pane to view the specific documentation on the module's GitHub page.
+
+To delete a module added from the Viam Registry, click the trash can icon in the upper-right corner of the module configuration pane in the **Components** tab.
+
+### Configure a module from the Viam Registry
-{{% alert title="Modules vs. modular resources" color="tip" %}}
+Once you have added a module from the Viam Registry, you can view and configure the module from the **Modules** subtab:
-A configured *module* can make one or more *modular resources* available for configuration.
+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.
+ All modules you have added to your robot appear under the **Deployed** section.
+This pane lists the models provided by the module, any [components](/components/) on your robot that are currently using those models, and allows you to configure [how the module updates](#configure-version-update-management-for-a-registry-module) when a new version is available from the Viam Registry.
+
+{{}}
+
+#### Configure version update management for a Registry module
+
+When you add a module to your robot, you can also configure how that module updates itself when a newer version becomes available from the Viam Registry.
+By default, a newly-added module is set to pin to the specific patch release (**Patch (X.Y.Z)**) of the version you added, meaning that the module will *never automatically update itself*.
+
+If you wish to allow automatic module updates when a new version of the module becomes available in the Viam Registry, you can set the **Version type** for your module in the **Modules** subtab.
+Updating to a newer version of a module brings new functionality and bug fixes, but requires restarting the module to apply the update.
+The following update options are available:
+
+- **Patch (X.Y.Z)**: Do not update to any other version.
+ This is the default.
+- **Minor (X.Y.*)**: Only update to newer patch releases of the same minor release branch.
+ The module will automatically restart and update itself whenever new updates within the same minor release are available in the Viam Registry.
+ For example, use this option to permit a module with version `1.2.3` to update to version `1.2.4` or `1.2.5` but not `1.3.0` or `2.0.0`.
+- **Major (X.*)**: Only update to newer minor releases of the same major release branch.
+ The module will automatically restart and update itself whenever new updates within the same major release are available in the Viam Registry.
+ For example, use this option to permit a module with version `1.2.3` to update to version `1.2.4` or `1.3.0` but not `2.0.0` or `3.0.0`.
+- **Latest**: Always update to the latest version of this module available from the Viam Registry as soon as a new version becomes available.
+
+When using the **Patch (X.Y.Z)** version type, you may select any patch version of the module from the **Version** drop down menu, including past versions if desired.
+
+The current deployed version of your module and the latest version of that module available from the Viam Registry are shown on this pane for your reference.
+
+{{% alert title="Caution" color="caution" %}}
+For any version type other than **Patch (X.Y.Z)**, the module will upgrade as soon as an update that matches that specified version type is available, which will **restart the module**.
+If, for example, the module provides a motor component, and the motor is running, it will stop while the module upgrades.
{{% /alert %}}
+### Configure a modular resource from a Registry module
+
+Once you have configured a module from the Viam Registry, 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).
+
+The following properties are available for modular resources:
+
+| Name | Type | Inclusion | Description |
+| ---- | ---- | --------- | ----------- |
+| `namespace` | string | **Required** | The namespace of the API (the first part of the {{< glossary_tooltip term_id="api-namespace-triplet" text="API namespace triplet">}}). See [Valid APIs to implement in your model](/extend/modular-resources/key-concepts/#valid-apis-to-implement-in-your-model) |
+| `type` | string | **Required** | The {{< glossary_tooltip term_id="subtype" text="subtype">}} of the API (the third part of the {{< glossary_tooltip term_id="api-namespace-triplet" text="API namespace triplet">}}). See [Valid APIs to implement in your model](/extend/modular-resources/key-concepts/#valid-apis-to-implement-in-your-model). |
+| `name` | string | **Required** | What you want to name this instance of your modular resource. |
+| `model` | string | **Required** | The full {{< glossary_tooltip term_id="model-namespace-triplet" text="model namespace triplet">}} of the modular resource's [model](/extend/modular-resources/key-concepts/#models). |
+| `depends_on` | array | Optional | The `name` of components you want to confirm are available on your robot alongside your modular resource. Often a [board](/components/board/). Unnecessary if you coded [implicit dependencies](/extend/modular-resources/key-concepts/#dependency-management). |
+
+All standard properties for configuration, such as `attributes` and `depends_on`, are also supported for modular resources.
+The `attributes` available vary depending on your implementation.
+
+{{< tabs >}}
+{{% tab name="JSON Template" %}}
+
+```json {class="line-numbers linkable-line-numbers"}
+{
+ "components": [
+ {
+ "namespace": "",
+ "type": "",
+ "model": "::",
+ "name": "",
+ "depends_on": [],
+ }
+ ],
+ "modules": [ ... ] // < INSERT YOUR MODULE CONFIGURATION >
+}
+```
+
+{{% /tab %}}
+{{% tab name="JSON Example" %}}
+
+The following is an example configuration for a base modular resource implementation.
+The configuration adds `acme:demo:mybase` as a modular resource from the module `my_base`.
+The custom model is configured as a component with the name "my-custom-base-1".
+You can send commands to the base according to the Viam [base API](/components/base/#api):
+
+```json {class="line-numbers linkable-line-numbers"}
+{
+ "components": [
+ {
+ "type": "board",
+ "name": "main-board",
+ "model": "pi"
+ },
+ {
+ "type": "base",
+ "name": "my-custom-base-1",
+ "model": "acme:demo:mybase",
+ "namespace": "rdk",
+ "attributes": {},
+ "depends_on": [ "main-board" ]
+ }
+ ],
+ "modules": [
+ {
+ "name": "my-custom-base",
+ "executable_path": "/home/my_username/my_base/run.sh"
+ }
+ ]
+}
+```
+
+{{% /tab %}}
+{{% /tabs %}}
+
+## Add a local module to your robot
+
+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).
+
+Follow these steps to configure a module and its modular resources locally:
+
+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.
+
### Make sure `viam-server` can access your executable
Ensure that your module executable is saved where the instance of `viam-server` behind your robot can read and execute it.
@@ -74,15 +214,15 @@ Add these properties to your module's configuration:
### Configure your modular resource
-Once you have configured a module as part of your robot configuration, you can add any number of the resources that module makes available to your robot by adding new components or services configured with your modular resources' new subtype or [model](/extend/modular-resources/key-concepts/#models).
+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).
The following properties are available for modular resources:
| Name | Type | Inclusion | Description |
| ---- | ---- | --------- | ----------- |
-| `namespace` | string | **Required** | The namespace of the [API](/extend/modular-resources/key-concepts/#apis) (the first part of the {{< glossary_tooltip term_id="api-namespace-triplet" text="API namespace triplet">}}). |
-| `type` | string | **Required** | The {{< glossary_tooltip term_id="subtype" text="subtype">}} of the [API](/extend/modular-resources/key-concepts/#apis) (the third part of the {{< glossary_tooltip term_id="api-namespace-triplet" text="API namespace triplet">}}). |
-| `name` | string | **Required** | What you want to name this instance of your modular resource. |
+| `namespace` | string | **Required** | The namespace of the API (the first part of the {{< glossary_tooltip term_id="api-namespace-triplet" text="API namespace triplet">}}). See [Valid APIs to implement in your model](/extend/modular-resources/key-concepts/#valid-apis-to-implement-in-your-model). |
+| `type` | string | **Required** | The {{< glossary_tooltip term_id="subtype" text="subtype">}} of the API (the third part of the {{< glossary_tooltip term_id="api-namespace-triplet" text="API namespace triplet">}}). See [Valid APIs to implement in your model](/extend/modular-resources/key-concepts/#valid-apis-to-implement-in-your-model). |
+| `name` | string | **Required** | A custom name for this instance of your modular resource. |
| `model` | string | **Required** | The full {{< glossary_tooltip term_id="model-namespace-triplet" text="model namespace triplet">}} of the modular resource's [model](/extend/modular-resources/key-concepts/#models). |
| `depends_on` | array | Optional | The `name` of components you want to confirm are available on your robot alongside your modular resource. Often a [board](/components/board/). Unnecessary if you coded [implicit dependencies](/extend/modular-resources/key-concepts/#dependency-management). |
@@ -117,22 +257,22 @@ You can send commands to the base according to the Viam [base API](/components/b
```json {class="line-numbers linkable-line-numbers"}
{
- "components": [
- {
- "type": "board",
- "name": "main-board",
- "model": "pi"
- },
- {
- "type": "base",
- "name": "my-custom-base-1",
- "model": "acme:demo:mybase",
- "namespace": "rdk",
- "attributes": {},
- "depends_on": [ "main-board" ]
- }
- ],
- "modules": [
+ "components": [
+ {
+ "type": "board",
+ "name": "main-board",
+ "model": "pi"
+ },
+ {
+ "type": "base",
+ "name": "my-custom-base-1",
+ "model": "acme:demo:mybase",
+ "namespace": "rdk",
+ "attributes": {},
+ "depends_on": [ "main-board" ]
+ }
+ ],
+ "modules": [
{
"name": "my-custom-base",
"executable_path": "/home/my_username/my_base/run.sh"
diff --git a/docs/extend/modular-resources/create/_index.md b/docs/extend/modular-resources/create/_index.md
index 77c04db62b..cebdbf2d43 100644
--- a/docs/extend/modular-resources/create/_index.md
+++ b/docs/extend/modular-resources/create/_index.md
@@ -1,37 +1,27 @@
---
-title: "Code your own modules to create custom resources"
+title: "Code your own modules to create modular resources"
linkTitle: "Create"
weight: 20
type: "docs"
tags: ["server", "rdk", "extending viam", "modular resources", "components", "services"]
-description: "Use the Viam module system to implement custom resources that can be included in any Viam-powered robot."
+description: "Use the Viam module system to implement modular resources that can be included in any Viam-powered robot."
no_list: true
---
-The Viam module system allows you to integrate custom {{< glossary_tooltip term_id="resource" text="resources" >}} ([components](/components/) and [services](/services/)) into any robot running on Viam.
+You can extend Viam by creating a custom [module](/extend/modular-resources/key-concepts/#modules) that provides one or more modular {{< glossary_tooltip term_id="resource" text="resources" >}} ([components](/components/) and [services](/services/)), and can be added to any robot running on Viam.
A common use case for modular resources is to create a new model that implements an existing Viam API.
-However, you can also create and expose new APIs with modular resources.
-{{% alert title="Modules vs. modular resources" color="tip" %}}
-
-A configured *module* can make one or more *modular resources* available for configuration.
-
-{{% /alert %}}
-
-Once you have created your custom resource, you can use the [Viam CLI](/manage/cli/) to [upload your custom resource](/extend/modular-resources/upload/) to the Viam Registry, to share it with other Viam users or just to other users in your organization.
+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, to share it with other Viam users or just to other users in your organization.
Alternatively, you can add your module locally to your robot without uploading to the Viam Registry.
-## Create a custom modular resource
-
-To create your own modular resource, code a module in Go or Python using the module support libraries provided by [Viam's SDKs](/program/apis/) that implements at least one new {{< glossary_tooltip term_id="model" text="model" >}} or {{< glossary_tooltip term_id="subtype" text="subtype" >}} of {{< glossary_tooltip term_id="resource" text="resource" >}}:
+## Create a custom module
-{{< tabs >}}
-{{% tab name="New Model" %}}
-Define a new model of a built-in resource subtype:
+To create a custom module, follow the steps below.
+A custom module can implement one or more [models](/extend/modular-resources/key-concepts/#models).
-1. [Code a new resource model](#code-a-new-resource-model) server implementing all methods the Viam RDK requires in `viam-servers`'s built-in API client of its subtype (ex. `rdk:component:base`).
+1. [Code a new resource model](#code-a-new-resource-model) server implementing all methods the Viam RDK requires in `viam-server`'s built-in API client of its subtype (ex. `rdk:component:base`).
Provide this as a file inside of your module, my_modular_resource.go or my_modular_resource.py.
Follow these instructions to find the appropriate source code before you start the process.
@@ -44,14 +34,17 @@ Provide this as a file inside of your module, my_modular_resource.go/client.go` or `/client.py` on [Viam's GitHub](https://github.com/viamrobotics/rdk/blob/main/).
+ See [Valid APIs to implement in your model](/extend/modular-resources/key-concepts/#valid-apis-to-implement-in-your-model) for more information.
- For example, the base client is defined in [rdk/components/base/client.go](https://github.com/viamrobotics/rdk/blob/main/components/base/client.go).
- Base your edits to my_modular_resource.go or my_modular_resource.py on this first file.
+ - Name your model according to the namespace of the built-in API you are implementing.
+ For more information see [Naming your model](/extend/modular-resources/key-concepts/#naming-your-model).
**To prepare to import your custom model and your chosen resource subtype's API into your main program and register them with your chosen SDK:**
- Find the subtype API as defined in the relevant `/.go` file in the RDK on Viam's GitHub.
- For example, the base subtype is defined in [rdk/components/base/base.go](https://github.com/viamrobotics/rdk/blob/fdff22e90b8976061c318b2d1ca3b1034edc19c9/components/base/base.go#L37).
- - Base your edits to main.go or main.py on this second file.
+ - Base your edits to main.go or main.py on this second file.
2. [Code a main program](#code-a-main-entry-point-program), main.go or main.py, that starts the module after adding your desired resources from the registry.
Import your custom model and API into the main program and register them with your chosen SDK.
@@ -59,28 +52,10 @@ This main program is the "entry point" to your module.
3. [Compile or package](#compile-the-module-into-an-executable) the module into a single executable that can receive a socket argument from Viam, open the socket, and start the module at the entry point.
-{{% /tab %}}
-{{% tab name="New Type" %}}
-Define a new {{< glossary_tooltip term_id="api-namespace-triplet" text="type or subtype" >}} of resource:
-
-1. Define the methods and messages of the new API in [protobuf](https://github.com/protocolbuffers/protobuf) and in Python or Go, then use a protobuf compiler to [generate the rest of the required protobuf files](https://grpc.io/docs/languages/python/generated-code/) based on that Python or Go code.
-Find detailed instructions in [Define a New Resource Subtype](create-subtype/).
-
-1. [Code at least one model](#code-a-new-resource-model) of this new resource.
-Make sure to implement every method required in your API definition.
-Import your custom models and APIs into the main program and register them with your chosen SDK.
-
-1. [Code a main program](#code-a-main-entry-point-program) that starts the module after adding your desired resources from the registry.
-This main program is the "entry point" to your module.
-
-1. [Compile or package](#compile-the-module-into-an-executable) the module into a single executable that can receive a socket argument from Viam, open the socket, and start the module at the entry point.
-
-{{% /tab %}}
-{{% /tabs %}}
-
### Code a new resource model
-The following example module registers a modular resource implementing Viam's built-in [Base API](/components/base/#api) [(rdk:service:base)](/extend/modular-resources/key-concepts/#models) as a new model, `"mybase"`:
+The following example module registers a modular resource implementing Viam's built-in [Base API](/components/base/#api) [(rdk:service:base)](/extend/modular-resources/key-concepts/#models) as a new model, `"mybase"`, using the model family `acme:demo:mybase`.
+For more information see [Naming your model](/extend/modular-resources/key-concepts/#naming-your-model).
The Go code for the custom model (mybase.go) and module entry point file (main.go) is adapted from the full demo modules available on the [Viam GitHub](https://github.com/viamrobotics/rdk/blob/main/examples/customresources).
@@ -390,7 +365,7 @@ func init() {
{{% tab name="Python"%}}
main.py is the Python module's entry point file.
-When executed, it registers the mybase custom model and API helper functions with the Python SDK and creates and starts the new module.
+When executed, it registers the `mybase` custom model and API helper functions with the Python SDK and creates and starts the new module.
Click to view sample code from main.py
diff --git a/docs/extend/modular-resources/examples/_index.md b/docs/extend/modular-resources/examples/_index.md
index ed582a4168..e232276576 100644
--- a/docs/extend/modular-resources/examples/_index.md
+++ b/docs/extend/modular-resources/examples/_index.md
@@ -15,13 +15,14 @@ aliases:
---
To familiarize yourself with creating and using modular resources, follow one of these example [tutorials](#tutorials) or clone one of these example [repositories](#repositories).
-Once you have created a modular resource, you can test your custom resource using the [Control tab](/manage/fleet/#remote-control) and program it using the [Viam SDKs](/program/apis/).
+Once you have created a modular resource, you can test your modular resource using the [Control tab](/manage/fleet/#remote-control) and program it using the [Viam SDKs](/program/apis/).
## Tutorials
{{< cards >}}
{{% card link="/extend/modular-resources/examples/rplidar/" customTitle="Add an RPlidar camera as a Modular Resource" %}}
{{% card link="/extend/modular-resources/examples/odrive/" customTitle="Add an ODrive motor as a Modular Resource" %}}
+ {{% card link="/extend/modular-resources/examples/csi/" customTitle="Add a CSI Camera as a Modular Resource" %}}
{{% card link="/extend/modular-resources/examples/custom-arm/" %}}
{{% card link="/extend/modular-resources/examples/tflite-module/" customTitle="Add a TensorFlow Lite Modular Service" %}}
{{% card link="/tutorials/custom/custom-base-dog/" %}}
diff --git a/docs/extend/modular-resources/examples/csi.md b/docs/extend/modular-resources/examples/csi.md
new file mode 100644
index 0000000000..c0e15f8cec
--- /dev/null
+++ b/docs/extend/modular-resources/examples/csi.md
@@ -0,0 +1,116 @@
+---
+title: "Add a CSI Camera as a Modular Resource"
+linkTitle: "CSI Camera"
+weight: 40
+type: "docs"
+description: "Use the viam:camera:csi model to add a CSI Camera to your robot."
+tags: ["board", "csi", "jetson", "serial", "module", "modular resources", "Python", "python SDK", "nvidia", "jetson orin", "jetson orin nano", "nano", "camera"]
+# SMEs: Sean
+---
+
+
+Many boards, like the Jetson Orin Nano, come with the option to use Camera Serial Interface (CSI) cameras, like [these cameras from E-con Systems](https://www.e-consystems.com/nvidia-jetson-agx-orin-cameras.asp) or [this camera from Seed Technologies](https://www.digikey.com/en/products/detail/seeed-technology-co.,-ltd/114992263/12396924).
+These cameras are excellent for utilizing embedded vision systems like Viam's [vision service](/services/vision/).
+Not all CSI cameras are supported by the [webcam camera model](/components/camera/webcam/).
+Instead, Viam supports CSI cameras by providing a [modular resource](/extend/modular-resources/) for your CSI camera: `viam:camera:csi`.
+
+This module includes a simple wrapper around `GStreamer` and a control interface for the **control** tab of the [Viam app](https://app.viam.com) so you can utilize the hardware accelerated GST plugins and use the embedded CSI cameras on your `jetson` boards with Viam.
+
+The module is open-sourced and available on [GitHub](https://github.com/seanavery/viam-csi).
+
+To use the CSI camera module, follow the [installation](#installation) and [configuration](#configuration) steps.
+
+## Installation
+
+On your robot's computer, download [the `viam:camera:csi` appimage](https://github.com/viamrobotics/odrive) and make it executable:
+
+``` {class="command-line" data-prompt="$"}
+sudo wget https://github.com/seanavery/viam-csi/releases/download/v0.0.2/viam-csi-0.0.2-aarch64.AppImage -O /usr/local/bin/viam-csi
+sudo chmod 755 /usr/local/bin/viam-csi
+```
+
+## Configuration
+
+{{< tabs name="Connect your CSI Module and Modular Resource">}}
+{{% tab name="JSON Template" %}}
+
+Go to your robot's page on the [Viam app](https://app.viam.com/).
+Navigate to the **Config** tab on your robot's page and select **Raw JSON** mode.
+
+Copy and paste the JSON object for the module into the modules array to add Viam's `csi-mr` module:
+
+```json {class="line-numbers linkable-line-numbers"}
+{
+ "modules": [
+ {
+ "executable_path": "",
+ "name": ""
+ }
+ ]
+}
+```
+
+Next, add the following JSON object to your components array to configure a `csi` [camera](/components/camera/) component with the name `my_test_csi_cam`:
+
+```json {class="line-numbers linkable-line-numbers"}
+ {
+ "model": "viam:camera:csi",
+ "attributes": {
+ "width_px": ,
+ "height_px": ,
+ "frame_rate": ,
+ "debug": ""
+ },
+ "depends_on": [],
+ "name": "",
+ "namespace": "rdk",
+ "type": "camera"
+ }
+```
+
+{{% /tab %}}
+{{% tab name="JSON Example" %}}
+
+```json {class="line-numbers linkable-line-numbers"}
+{
+ "modules": [
+ {
+ "executable_path": "/usr/bin/csi-mr",
+ "name": "csi_cam_module"
+ }
+ ],
+ "components": [
+ {
+ "model": "viam:camera:csi",
+ "attributes": {
+ "width_px": 1920,
+ "height_px": 1080,
+ "frame_rate": 30,
+ "debug": true
+ },
+ "depends_on": [],
+ "name": "my_test_csi_cam",
+ "namespace": "rdk",
+ "type": "camera"
+ }
+ ]
+}
+```
+
+{{% /tab %}}
+{{< /tabs >}}
+
+Save the config.
+Edit and fill in the attributes as applicable.
+
+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.
+
+The following attributes are available for the `viam:camera:csi` model:
+
+| Name | Type | Inclusion | Description |
+| ---- | ---- | --------- | ----------- |
+| `width_px` | int | Optional | Width of the image this camera captures in pixels.
Default: `1920` |
+| `height_px` | int | Optional | Height of the image this camera captures in pixels.
Default: `1080` |
+| `frame_rate` | int | Optional | The image capture frame rate this camera should use.
Default: `30` |
+| `video_path` | string | Optional | The filepath to the input sensor of this camera on your board. If none is given, your robot will attempt to detect the video path automatically.
Default: `"0"` |
+| `debug` | boolean | Optional | Whether or not you want debug input from this camera in your robot's logs.
Default: `false` |
diff --git a/docs/extend/modular-resources/examples/tflite-module.md b/docs/extend/modular-resources/examples/tflite-module.md
index 639b45cf74..d2b97dbb4d 100644
--- a/docs/extend/modular-resources/examples/tflite-module.md
+++ b/docs/extend/modular-resources/examples/tflite-module.md
@@ -18,7 +18,7 @@ This code is for instructional purposes only, and is not intended for production
You can find the example files in the [Viam C++ SDK](https://github.com/viamrobotics/viam-cpp-sdk):
-- [`example_mlmodelservice_tflite.cpp`](https://github.com/viamrobotics/viam-cpp-sdk/blob/main/src/viam/examples/modules/example_mlmodelservice_tflite.cpp) - an example module which provides the `MLModelService` modular resource capable of running any TensorFlow Lite model.
+- [`example_mlmodelservice_tflite.cpp`](https://github.com/viamrobotics/viam-cpp-sdk/blob/main/src/viam/examples/modules/tflite/main.cpp) - an example module which provides the `MLModelService` modular resource capable of running any TensorFlow Lite model.
- [`example_audio_classification_client.cpp`](https://github.com/viamrobotics/viam-cpp-sdk/blob/main/src/viam/examples/mlmodel/example_audio_classification_client.cpp) - an example inference client which generates audio samples and invokes the `example_mlmodelservice_tflite` module to classify those samples using the [`yamnet/classification` TensorFlow Lite model](https://tfhub.dev/google/lite-model/yamnet/classification/tflite/1).
## Build the C++ SDK
diff --git a/docs/extend/modular-resources/key-concepts.md b/docs/extend/modular-resources/key-concepts.md
index 89fe2cae8f..375b4c162f 100644
--- a/docs/extend/modular-resources/key-concepts.md
+++ b/docs/extend/modular-resources/key-concepts.md
@@ -8,56 +8,113 @@ description: "The key concepts behind how Viam's resource APIs and models are un
no_list: true
---
-`viam-server` [manages](#management) modular {{< glossary_tooltip term_id="resource" text="resources" >}} configured on your robot the same way it manages resources that are already built into the Robot Development Kit [(RDK)](/internals/rdk/).
-Two key concepts exist across all Viam resources, both built-in and modular, that make this flexible management possible: uniquely namespaced resource [*APIs*](#apis) and [*models*](#models).
+You can extend the features of an existing {{< glossary_tooltip term_id="resource" text="resource" >}} API by [creating a custom module](/extend/modular-resources/create/) to define a new [model](#models) that implements that API.
+A custom module can provide one or more modular resource models.
-If you create your [own module](/extend/modular-resources/create/), you must register any new APIs and models you define in your model with Viam's model registry in the appropriate namespaces to [configure](/extend/modular-resources/configure/) the modular resource on your robot.
+## Modules
-## APIs
+A *module* provides one or more [*modular resources*](#resources), and is a flexible way to extend the functionality of your Viam robot.
+Modules run alongside `viam-server` as a separate process, communicating with `viam-server` over a UNIX socket.
+A module provides definitions for one or more pairs of [APIs](#valid-apis-to-implement-in-your-model) and [models](#models).
-{{% alert title="Modules vs. modular resources" color="tip" %}}
+When the module initializes, it registers those pairs on your robot, making the functionality defined by that pair available for use.
-A configured *module* can make one or more *modular resources* available for configuration.
+You can [upload your own modules to the Viam Registry](/extend/modular-resources/upload/) or can [add existing modules from the Registry](/extend/modular-resources/configure/).
-{{% /alert %}}
+See [Creating a custom module](/extend/modular-resources/create/) for more information.
-Every Viam {{< glossary_tooltip term_id="resource" text="resource" >}} subtype exposes an [application programming interface (API)](https://en.wikipedia.org/wiki/API).
-This can be understood as a description of how you can interact with that resource.
-Each API is described through [protocol buffers](https://developers.google.com/protocol-buffers).
-Viam SDKs [expose these APIs](/internals/robot-to-robot-comms/).
+## Resources
-### Namespace
+A resource is a [component](/components/) or [service](/services/).
+Each component or service is typed by a proto API, such as the [component proto definitions](https://github.com/viamrobotics/api/tree/main/proto/viam/component).
-Each Viam resource's API is uniquely namespaced as a colon-delimited-triplet in the form of `namespace:type:subtype`.
+Any resource on your robot needs to implement either one of these [existing Viam APIs](#valid-apis-to-implement-in-your-model), or a custom interface.
-For example:
+A *modular resource* is a resource that is provided by a [module](#modules), and not built-in to the RDK.
+A modular resource runs in the module process. This differs from built-in resources, which run as part of `viam-server`.
-- The API of built-in component [camera](/components/camera/) is `rdk:component:camera`, which exposes methods such as `GetImage()`.
-- The API of built-in service [vision](/services/vision/) is `rdk:service:vision`, which exposes methods such as `GetDetectionsFromCamera()`.
+## Models
-{{% alert title="Tip" color="tip" %}}
-You can see built-in Viam resource APIs in the [Viam GitHub](https://github.com/viamrobotics/api).
-{{% /alert %}}
+A *model* describes a specific implementation of a [resource](#resources) that implements (speaks) its API.
+Models allow you to control different instances of resource with a consistent interface, even if the underlying implementation differs.
-## Models
+For example, some DC motors communicate using [GPIO](/components/board/), while other DC motors use serial protocols like the [SPI bus](/components/board/#spis).
+Regardless, you can power any motor model that implements the `rdk:component:motor` API with the `SetPower()` method.
-A *model* describes a specific implementation of a resource that implements (speaks) its API.
-Models allow you to control different instances of resource {{< glossary_tooltip term_id="api-namespace-triplet" text="subtypes" >}} with a consistent interface.
+Models are uniquely namespaced as colon-delimited-triplets in the form `namespace:family:name`.
+See [Naming your model](/extend/modular-resources/key-concepts/#naming-your-model) for more information.
-For example:
+Models are either:
-Some DC motors use just [GPIO](/components/board/), while other DC motors use serial protocols like [SPI bus](/components/board/#spis).
-Regardless, you can power any motor model that implements the `rdk:component:motor` API with the `SetPower()` method.
+- Built into the RDK, and included when you [install `viam-server`](/installation/) or when you use one of the [Viam SDKs](/program/apis/).
+- Provided in custom modules available for download from [the Viam Registry](https://app.viam.com/module), and are written by either Viam or community users.
-### Namespace
+### Built-in models
-Models are also uniquely namespaced as colon-delimited-triplets in the form of `namespace:family:name`.
+Viam provides many built-in models that implement API capabilities, each using `rdk` as the `namespace`, and `builtin` as the `family`.
+These models run within `viam-server`.
For example:
- The `rdk:builtin:gpio` model of the `rdk:component:motor` API provides RDK support for [GPIO-controlled DC motors](/components/motor/gpio/).
- The `rdk:builtin:DMC4000` model of the same `rdk:component:motor` API provides RDK support for the [DMC4000](/components/motor/dmc4000/) motor.
+### Custom models
+
+The [Viam Registry](https://app.viam.com/registry) makes available both Viam-provided and community-written modules for download and use on your robot.
+These models run outside `viam-server` as a separate process.
+
+#### Valid APIs to implement in your model
+
+When implementing a custom model of an existing [component](/components/), valid [APIs](/program/apis/) are always:
+
+- `namespace`: `rdk`
+- `type`: `component`
+- `subtype`: any one of [these component proto files](https://github.com/viamrobotics/api/tree/main/proto/viam/component).
+
+When implementing a custom model of an existing [service](/services/), valid [APIs](/program/apis/) are always
+
+- `namespace`: `rdk`
+- `type`: `service`
+- `subtype`: any one of [these service proto files](https://github.com/viamrobotics/api/tree/main/proto/viam/service).
+
+#### Naming your model
+
+If you are [creating a custom module](/extend/modular-resources/create/) and [uploading that module](/extend/modular-resources/upload/) to the Viam Registry, ensure your model name meets the following requirements:
+
+- The namespace of your model **must** match the [namespace of your organization](/manage/fleet/organizations/#create-a-namespace-for-your-organization).
+ For example, if your organization uses the `acme` namespace, your models must all begin with `acme`, like `acme:demo:mybase`.
+- Your model triplet must be all-lowercase.
+- Your model triplet may only use alphanumeric (`a-z` and `0-9`), hyphen (`-`), and underscore (`_`) characters.
+
+In addition, you should chose a name for the `family` of your model based on the whether your module implements a single model, or multiple models:
+
+- If your module provides a single model, the `family` should match the `subtype` of whichever API your model implements.
+ For example, the Intel Realsense module `realsense`, available from [the Viam Registry](https://app.viam.com/module/viam/realsense), implements the `camera` component API, so it is named as follows:
+
+ ```json {class="line-numbers linkable-line-numbers"}
+ {
+ "api": "rdk:component:camera",
+ "model": "viam:camera:realsense"
+ }
+ ```
+
+- If your module provides multiple models, the `family` should describe the common functionality provided across all the models of that module.
+ For example, the ODrive module `odrive`, available from [the Viam Registry](https://app.viam.com/module/viam/odrive), implements several `motor` component APIs, so it is named as follows:
+
+ ```json {class="line-numbers linkable-line-numbers"}
+ {
+ "api": "rdk:component:motor",
+ "model": "viam:odrive:serial"
+ },
+ {
+ "api": "rdk:component:motor",
+ "model": "viam:odrive:canbus"
+ }
+ ```
+
+A model with the `viam` namespace is always Viam-provided.
+
## Management
The Robot Development Kit (RDK) `viam-server` provides automatically manages modular resources to function like built-in resources:
diff --git a/docs/extend/modular-resources/upload/_index.md b/docs/extend/modular-resources/upload/_index.md
index 4bf3f6ed77..e885205da0 100644
--- a/docs/extend/modular-resources/upload/_index.md
+++ b/docs/extend/modular-resources/upload/_index.md
@@ -106,7 +106,7 @@ To upload your custom module to the Viam Registry, either as a public or private
```
{{% alert title="Important" color="note" %}}
- If you are publishing a public module (`visibility: "public"`), the [namespace of your model](/extend/modular-resources/key-concepts/#namespace-1) 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/installation/prepare/jetson-nano-setup.md b/docs/installation/prepare/jetson-nano-setup.md
index 19db3c3808..fa28be4785 100644
--- a/docs/installation/prepare/jetson-nano-setup.md
+++ b/docs/installation/prepare/jetson-nano-setup.md
@@ -19,13 +19,6 @@ Follow this guide to set up the [Jetson Nano Developer Kit](https://developer.nv
{{}}
-{{% alert title="Stability Notice" color="note" %}}
-
-Support for this board is experimental.
-Stability is not guaranteed.
-
-{{% /alert %}}
-
{{% alert title="Important" color="note" %}}
This guide assumes that you have a Jetson Nano Developer Kit or a Jetson Orin Nano Developer Kit with a Jetson module and reference carrier board.
diff --git a/docs/installation/prepare/microcontrollers/_index.md b/docs/installation/prepare/microcontrollers/_index.md
index 282f00e09a..65334d10fe 100644
--- a/docs/installation/prepare/microcontrollers/_index.md
+++ b/docs/installation/prepare/microcontrollers/_index.md
@@ -244,12 +244,11 @@ The`esp32` [board](/components/board/) model is not currently provided for you a
TODO: UNCOMMENT WHEN AVAILABLE IN APP UI, AND MOVE THIS CHUNK TO BOARD PAGE (SG)
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.
-Enter a name for your board, select the type `board`, and select the `numato` model.
+Click on the **Components** subtab and click **Create component**.
+Select the `board` type, then select the `numato` model.
+Enter a name for your board and click **Create**.
-Click **Create component**.
-
- ![An example configuration for an esp21 board in the Viam app Config Builder.](/components/board/esp32-ui-config.png)
+ ![An example configuration for an esp32 board in the Viam app Config Builder.](/components/board/esp32-ui-config.png)
Edit and fill in the attributes as applicable.
-->
diff --git a/docs/manage/CLI.md b/docs/manage/CLI.md
index 25c5d5ab5e..a19dcf4ffd 100644
--- a/docs/manage/CLI.md
+++ b/docs/manage/CLI.md
@@ -99,23 +99,64 @@ To later update the Viam CLI tool, you can use the steps above to reinstall the
## Authenticate
-Once you have successfully installed the Viam CLI, you need to authenticate your device for CLI usage with your Viam app account before you can control your robots with the CLI.
-Do this by issuing the command:
+Once you have [installed the Viam CLI](#install), you must authenticate your CLI session with Viam in order to run CLI commands.
-```sh {class="command-line" data-prompt="$"}
-viam login
-```
+You can authenticate your CLI session using either a personal access token or an organization API key.
+To use an organization API key to authenticate, you must first [create an organization API key](#create-an-organization-api-key).
+
+* To authenticate your CLI session using a personal access token:
+
+ ```sh {class="command-line" data-prompt="$"}
+ viam login
+ ```
+
+ This will open a new browser window with a prompt to start the authentication process.
+ If a browser window does not open, the CLI will present a URL for you to manually open in your browser.
+ Follow the instructions to complete the authentication process.
-This will open a new browser window with a prompt to start the authentication process.
-If a browser window does not open, the CLI will present a URL for you to manually open in your browser.
-Follow the instructions to complete the authentication process.
+* To authenticate your CLI session using an organization API key:
+
+ ```sh {class="command-line" data-prompt="$"}
+ viam login api-key --key-id