Part 1: Vision Pipeline
Goal: Get a computer vision pipeline working.
Skills: Connect a machine to Viam, configure components with the Viam CLI, use fragments to add preconfigured services.
Time: ~10 min
Prerequisites
Before starting this tutorial, you need the can inspection simulation running. Follow the Gazebo Simulation Setup Guide to:
- Build the Docker image with Gazebo Harmonic
- Create a machine in Viam and get credentials
- Start the container with your Viam credentials
Once you see “Can Inspection Simulation Running!” in the container logs and your machine shows Live in the Viam app, return here to continue.
You also need the Viam CLI installed and authenticated. See Viam CLI overview for installation and authentication instructions.
What you're working with
The simulation runs Gazebo Harmonic inside a Docker container. It simulates a conveyor belt with cans (some dented) passing under an inspection camera. viam-server runs on the Linux virtual machine inside the container and connects to Viam’s cloud, just like it would on a physical machine. Everything you configure applies to the simulated hardware.
1.1 Verify Your Machine is Online
If you followed the setup guide, your machine should already be online.
Run:
viam machines status --machine=<machine-id>
Look for status: live in the output. If your machine isn’t live yet, check that the Docker container is running and that the logs show “Can Inspection Simulation Running!”.
Ordinarily, after creating a machine in Viam, you would download and install viam-server together with the cloud credentials for your machine. For this tutorial, we’ve already installed viam-server and launched it in the simulation Docker container.
1.2 Get Your Part ID
Your machine is online but empty. To configure your machine, you will add components and services to your machine part. Your machine part is the compute hardware — in this tutorial, a virtual machine running Linux in the Docker container.
Get the part ID for inspection-station-1-main:
viam machines part list --machine=<machine-id>
Copy the part ID from the output. You’ll use it in every command that follows.
1.3 Configure the Camera
You’ll now add the camera as a component.
Add a camera component
Add the gz-camera module’s rgb-camera model and name it inspection-cam:
viam machines part add-resource \
--part=<part-id> \
--name=inspection-cam \
--model-name=gz-camera:gz-camera:rgb-camera
Configure the camera
Set the camera ID so the module knows which Gazebo camera to connect to:
viam resource update \
--part=<part-id> \
--resource-name=inspection-cam \
--config '{"id": "/inspection_camera"}'
What happened behind the scenes
You declared “this machine has a camera called inspection-cam” by running two CLI commands. viam-server picks up configuration changes immediately — no restart needed. It loaded the camera module, added the camera component, and made it available through Viam’s standard camera API. Software you write, other services, and UI components all use the same API. Using the API as an abstraction means everything still works if you swap cameras.
1.4 Test the Camera
The easiest way to verify the camera is working is to use the Viam app’s built-in test panel, which shows a live video feed.
- Open app.viam.com and navigate to your machine
- Click the CONFIGURE tab and select
inspection-cam - Expand the TEST section at the bottom of the camera’s configuration panel
You should see a live overhead view of the conveyor/staging area.
Checkpoint
Your camera is working. You can stream video and capture images from the simulated inspection station.
1.5 Add a vision pipeline with a fragment
Now you’ll add machine learning to run inference on your camera feed. You need two services:
- ML model service that loads a trained model for the inference task
- Vision service that connects the camera to the model and returns detections
Instead of adding each service manually, you’ll use a fragment. A fragment is a reusable block of configuration that can include components, services, modules, and ML models. Fragments let you share tested configurations across machines and teams.
The try-vision-pipeline fragment includes an ML model service loaded with a can defect detection model and a vision service wired to that model. The fragment accepts a camera_name variable so it works with any camera.
Add the fragment
Apply the try-vision-pipeline fragment to your machine part:
viam machines part fragments add \
--part=<part-id> \
--fragment=<try-vision-pipeline-fragment-id>
Set the camera variable
The fragment uses a camera_name variable to wire the vision service to your specific camera. Set it in the machine’s JSON configuration:
viam machines part run \
--part=<part-id> \
--data='{"name": "inspection-station-1-main"}' \
viam.app.v1.RobotService.GetRobotPart
Then update the fragment’s variable override. Open the machine’s JSON config and add the fragment_mods entry:
{
"fragment_mods": [
{
"fragment_id": "<try-vision-pipeline-fragment-id>",
"mods": [
{
"$ set": {
"camera_name": "inspection-cam"
}
}
]
}
]
}
Save this as fragment-vars.json and apply it with the app API, or set the variable in the Viam app if you prefer.
What the fragment added
The fragment added two services and their dependencies to your machine:
- model-service: An ML model service running TensorFlow Lite with the
can-defect-detectionmodel from the Viam registry. This model classifies cans as PASS or FAIL. - vision-service: A vision service that takes images from your camera, runs them through the ML model, and returns structured detection results.
The fragment also added the TFLite CPU module and the ML model package. Everything is wired together and ready to use.
Fragments and reuse
This fragment works with any camera. If you were using a USB webcam instead of the simulation camera, you’d set camera_name to whatever you named your webcam component. The ML pipeline stays the same. This is how fragments enable reuse across different hardware setups.
Test the vision service
- Open app.viam.com and navigate to your machine
- Click the CONFIGURE tab and find
vision-service - Expand the TEST section, select
inspection-camas the camera source, and set Detections/Classifications toLive
What you've built
A complete ML inference pipeline. The vision service grabs an image from the camera, runs it through the TensorFlow Lite model, and returns structured detection results. This same pattern works for any ML task: object detection, classification, segmentation. Swap the model and camera, and the pipeline still works.
Checkpoint
You added a camera component and used a fragment to add a complete ML vision pipeline — entirely from the command line. The system can detect defective cans. Next, you’ll set up continuous data capture so every detection is recorded and queryable.
Explore the JSON configuration
Everything you configured is stored as JSON in Viam’s cloud. You can inspect the full configuration at any time:
viam metadata read --part-id=<part-id>
You’ll see your camera component, the fragment reference, and how the fragment’s services connect to your camera. As configurations grow more complex, the JSON view helps you understand how components and services connect.
Continue to Part 2: Data Capture →
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!