Generic Component

The generic component subtype enables you to add support for unique types of hardware that do not already have an appropriate API defined for them.

For example, when using an arm component, it makes sense to use the arm API, which provides specific functionality an arm component needs, such as moving to position or stopping movement. However, if you want to use an LED display for example, you need very different functionality that isn’t currently exposed in any API. Instead, you can use the generic component API to add support for your unique type of hardware, like LED displays, to your machine.

Use generic for a modular resource model that represents a unique type of hardware. If you are adding new high-level software functionality, rather than supporting new hardware components, use the generic service instead.

There are no built-in generic component models (other than fake).

Supported models

Before creating a new generic component, check whether one of the following modular resources supports your use case.

Built-in models

For configuration information, click on the model name:

ModelDescription
fakeA model used for testing, with no physical hardware.

Modular resources

Search for additional generic models that you can add from the Viam Registry:

For configuration information, click on the model name:

Model
Description

Control your board with Viam’s client SDK libraries

To get started using Viam’s SDKs to connect to and control your machine, go to your machine’s page on the Viam app, navigate to the CONNECT tab’s Code sample page, select your preferred programming language, and copy the sample code generated.

When executed, this sample code will create a connection to your machine as a client. Then control your machine programmatically by getting your generic component from the machine with FromRobot and adding API method calls, as shown in the following examples.

These examples assume you have a board called “my_board” configured as a component of your machine. If your board has a different name, change the name in the code.

Be sure to import the generic component package for the SDK you are using:

from viam.components.generic import Generic
import (
  "go.viam.com/rdk/components/generic"
)
#include <viam/sdk/components/generic/generic.hpp>

API

The generic component supports the following method:

Method NameDescription
GetGeometriesGet all the geometries associated with the generic component in its current configuration, in the frame of the generic component.
DoCommandSend or receive model-specific commands.
CloseSafely shut down the resource and prevent further use.

GetGeometries

Get all the geometries associated with the generic component in its current configuration, in the frame of the generic component. The motion and navigation services use the relative position of inherent geometries to configured geometries representing obstacles for collision detection and obstacle avoidance while motion planning.

Parameters:

  • extra (Optional[Dict[str, Any]]): Extra options to pass to the underlying RPC call.
  • timeout (Optional[float]): An option to set how long to wait (in seconds) before calling a time-out and closing the underlying RPC call.

Returns:

  • (List[Geometry]): The geometries associated with the generic component, in any order.

For more information, see the Python SDK Docs.

my_generic = Generic.from_robot(robot=robot, name="my_generic_component")

geometries = await my_generic.get_geometries()

if geometries:
    # Get the center of the first geometry
    print(f"Pose of the first geometry's centerpoint: {geometries[0].center}")

DoCommand

Execute model-specific commands. If you are implementing your own generic component and add features that have no built-in API method, you can access them with DoCommand.

Parameters:

Returns:

my_generic = Generic.from_robot(robot=robot, name="my_generic_component")

raw_dict = {
  "command": "raw",
  "raw_input": "home"
}
await my_generic.do_command(raw_dict)

For more information, see the Python SDK Docs.

Parameters:

Returns:

myGeneric, err := generic.FromRobot(robot, "my_generic_component")

resp, err := myGeneric.DoCommand(ctx, map[string]interface{}{"command": "example"})

For more information, see the Go SDK Code.

Parameters:

Returns:

auto my_generic = robot->resource_by_name<GenericComponent>("my_generic_component");
auto example = std::make_shared<ProtoType>(std::string("example"));
AttributeMap command =
    std::make_shared<std::unordered_map<std::string, std::shared_ptr<ProtoType>>>();
command->insert({{std::string("command"), example}});
auto resp = my_generic->do_command(command);

For more information, see the C++ SDK Docs

Close

Safely shut down the resource and prevent further use.

Parameters:

  • None

Returns:

  • None
my_generic = Generic.from_robot(robot, "my_generic")

await my_generic.close()

For more information, see the Python SDK Docs.

Parameters:

  • ctx (Context): A Context carries a deadline, a cancellation signal, and other values across API boundaries.

Returns:

  • (error) : An error, if one occurred. Close will never return an error for a generic resource.
myGeneric, err := generic.FromRobot(robot, "my_generic")

err := myGeneric.Close(ctx)

For more information, see the Go SDK Docs.

There is no need to explicitly close a generic component’s resource in C++, as resource destruction is handled automatically by the generic component’s class destructor when variables exit scope.

Troubleshooting

You can find additional assistance in the Troubleshooting section.

You can also ask questions in the Community Discord and we will be happy to help.