KINOVA KORTEX™ API

repository·master·Indexed 41 days ago

https://github.com/kinovarobotics/kinova-kortex2_gen3_g3l

A standardized interface for controlling Kinova Gen3 and Gen3 lite robotic arms using C++, Python, or Modbus. The API utilizes Google Protocol Buffers for structured data exchange and supports both TCP (Port 10000) for commands and UDP (Port 10001) for real-time data. Documentation includes guides for Ethernet Bridge configuration, C++ development environment setup using CMake and Conan V1.X, and implementation of leader-follower control systems.

Tokens
395.4K
Snippets
708
Records
1.2K
Agent score
49%

What's inside Kortex

  1. Use the Python GripperConfig API

    master

    The GripperConfig API in Python provides interfaces for configuring and monitoring gripper hardware. It includes RPC (Remote Procedure Call) methods for interacting with the gripper and data classes for representing gripper state and configuration.

    Key components include:

    • RPCs: Methods used to send commands to the gripper.
    • Data Classes: Objects used to structure gripper configuration data.
    • Enumerators: Specific sets of constants used for status and safety, such as RobotiqGripperStatusFlags and SafetyIdentifier.
  2. Explore the Kortex C++ API Reference

    master

    The Kortex C++ API is organized into several functional modules. Developers can interact with the robot through these primary namespaces:

    • ActuatorConfig: Configuration for individual actuators (e.g., AxisOffsets, ControlLoop, TorqueOffset).
    • ActuatorCyclic: High-frequency cyclic communication for actuators (e.g., Command, Feedback).
    • Api: Core API services and error handling (ErrorCodes, SubErrorCodes).
    • Base: Fundamental robot operations, including Action management, ArmState, Gripper control, Joint limits, Mapping, ProtectionZone, and Sequence execution.
    • BaseCyclic: Cyclic communication for base robot components.
    • Common: Shared types and utilities like Connection, Timestamp, Unit, and ArmState.
    • ControlConfig: Configuration for motion control, including KinematicLimits, PayloadInformation, and ToolConfiguration.
    • DeviceConfig: Hardware-level configuration such as FirmwareVersion, SerialNumber, and SafetyConfiguration.
    • DeviceManager: Management of connected devices and DeviceHandles.
    • GripperConfig & GripperCyclic: Configuration and cyclic control for grippers.
    • InterconnectConfig & InterconnectCyclic: Configuration and cyclic control for external interfaces like GPIO, I2C, UART, and Ethernet.
    • ProductConfiguration: Hardware identity and assembly details (e.g., EndEffectorType, ArmLaterality).
    • Session: Connection management and CreateSessionInfo.
    • VisionConfig: Configuration for vision sensors, including IntrinsicParameters, ExtrinsicParameters, and SensorSettings.
  3. ProductConfiguration (Python) API Overview

    master

    The ProductConfiguration Python API provides interfaces to interact with the device's configuration data. It is structured into RPCs (Remote Procedure Calls) for performing actions and Data Classes (Messages) for representing the configuration state.

    Key components include:

    • RPCs: Methods used to query or modify product configurations.
    • Messages: Data structures representing the complete configuration or specific components like end-effectors.
    • Enumerators: Strongly typed constants for defining properties such as arm laterality, base types, and module types.
  4. ProductConfiguration C++ API Overview

    master
    The ProductConfiguration C++ API provides access to the hardware configuration details of a Kinova device. It allows developers to inspect the complete configuration of a given device and identify specific hardware components such as end-effectors. The API is structured around RPCs (Remote Procedure Calls) and specific data classes (Messages) and Enumerators that define the hardware capabilities.
  5. Explore the Kortex Python API structure

    master

    The Kortex Python API is organized into several functional modules. Developers can interact with the robot through these primary namespaces:

    • ActuatorConfig: Configuration for individual actuators (e.g., AxisOffsets, ControlLoop, TorqueOffset).
    • ActuatorCyclic: High-frequency cyclic data for actuators (e.g., Command, Feedback).
    • Api: Core API services and error handling (ErrorCodes, SubErrorCodes).
    • Base: Fundamental robot abstractions including ArmState, Gripper commands, JointAngles, Pose, Waypoint, and Sequence management.
    • BaseCyclic: High-frequency cyclic communication for base robot functions.
    • Common: Shared data types like Timestamp, Connection, Unit, and ArmState.
    • ControlConfig: Configuration for motion control, including PayloadInformation, KinematicLimits, and ToolConfiguration.
    • DeviceConfig: Hardware-level configuration such as FirmwareVersion, SerialNumber, and SafetyStatus.
    • DeviceManager: Management of device handles.
    • GripperConfig & GripperCyclic: Configuration and high-frequency control for grippers.
    • InterconnectConfig & InterconnectCyclic: Configuration and cyclic data for external interfaces like GPIO, I2C, and Ethernet.
    • ProductConfiguration: Hardware identity and model information.
    • Session: Connection and session management.
    • VisionConfig: Configuration for vision sensors, including IntrinsicParameters and ExtrinsicParameters.
  6. Subscribe to robot notifications using Publish/Subscribe

    master

    The robot base uses a Publish/Subscribe design pattern for unsolicited messages. Instead of polling, your application subscribes to specific topics. When a change occurs on a topic, the robot sends a notification to all active subscribers.

    To receive notifications, implement a callback function and register it using the appropriate topic method on the base object (e.g., base.OnNotification<TopicName>).

    # In this example, when a user is created `notification_callback` will be called because we register it as a
    # handler for `ConfigurationChange` topic notifications.
    def notification_callback(data):
    	print("********************************")
    	print("**  Callback function called  **")
    	print(json_format.MessageToJson(data))
    	print("********************************")
    
    # Subscribe to ConfigurationChange notifications
    notif_handle = base.OnNotificationConfigurationChangeTopic(notification_callback, Base_pb2.NotificationOptions())
  7. Choose a Transport protocol (TCP vs UDP)

    master

    The Transport class identifies the robot base via a communication protocol, IP address, and port. Kinova provides two pre-defined subclasses of the ITransportClient interface:

    • TCPTransport: Use this for high-level robot control, configuration, and general purposes. It is the recommended protocol for Python users.
    • UDPTransport: Use this only for low-level cyclic communication at 1kHz via the Kinova::Api::BaseCyclic service.

    Note for Python users: While low-level control is available in the Python API, it is not recommended for performance reasons. Use TCPTransport instead.

  8. Choose the correct TransportClient for your communication needs

    master

    The TransportClient classes identify the robot base via an IP address and port. Kinova provides two primary implementations of the ITransportClient interface:

    • TransportClientTcp: Use this for high-level robot control, configuration, and general API usage. It is suitable for most tasks that do not require extremely high-frequency command transmission.
    • TransportClientUdp: Use this exclusively for low-level cyclic communication at 1kHz via the Kinova::Api::BaseCyclic service.

    Both classes implement the ITransportClient interface, which includes methods for connect, disconnect, send, onMessage, getTxBuffer, and getMaxTxBufferSize.

    namespace k_api = Kinova::Api;
    
    k_api::TransportClientTcp* transport = new k_api::TransportClientTcp();
    transport->connect(IP_ADDRESS, PORT);
  9. Manipulate Action parameters using the oneof pattern in C++

    master

    The Action class uses a Protobuf oneof pattern for its action_parameters. This means an Action object can only hold one type of parameter at a time (e.g., either JointSpeeds, ConstrainedPose, or Snapshot). Setting a new parameter automatically clears the previous one.

    To interact with these parameters in C++, use the following patterns:

    1. Setting Complex Message Parameters

    For parameters that are messages (like ConstrainedPose or Snapshot), use mutable_<field>() to get a pointer to the object you can modify, or set_allocated_<field>(ptr) to transfer ownership of an existing pointer.

    2. Setting Primitive Parameters

    For simple types like uint32 (e.g., toggle_admittance_mode), use set_<field>(value).

    3. Checking the Active Parameter

    Use action_parameters_case() to determine which parameter is currently set, or use the has_<field>() helper methods.

    // Example: Setting a reach pose
    Action action;
    auto* pose = action.mutable_reach_pose();
    // ... configure pose object ...
    
    // Example: Checking what is set
    if (action.action_parameters_case() == Action::kReach_pose) {
        const auto& pose = action.reach_pose();
        // ... use pose ...
    }
  10. Manage ConfigurationChangeNotification oneof fields in C++

    master

    The ConfigurationChangeNotification class uses a oneof structure to represent different types of configuration changes. Because it is a oneof, only one field can be set at a time. Setting a new field automatically clears the previous one.

    Supported fields in the oneof include:

    • user_profile_handle (kUser_profile_handle)
    • protection_zone_handle (kProtection_zone_handle)
    • safety_handle (kSafety_handle)
    • network_handle (kNetwork_handle)
    • ssid (kSsid)

    To interact with these fields, use the following patterns:

    Checking the current field

    Use has_<field_name>() to check if a specific field is currently set. Use configuration_change_case() to determine which field is active.

    Modifying fields

    • mutable_<field_name>(): Returns a pointer to the field's object. If another field was previously set, it is cleared. This is the preferred way to modify an existing field's contents.
    • set_allocated_<field_name>(pointer): Takes ownership of a pointer to a new object. If the pointer is NULL, it clears the oneof case.
    • clear_<field_name>(): Frees the field and resets the oneof case to CONFIGURATION_CHANGE_NOT_SET.

    Retrieving and releasing ownership

    • const <field_name>() const: Returns a constant reference to the field if it is set.
    • release_<field_name>(): Returns the pointer to the field and transfers ownership to the caller. The oneof case is cleared after this call.