BotRobotProfile bot.robot-profile@1

Generated at from openvibe-contracts v0.97.0 and openvibe-sdk v0.26.0.

Version
1.0.0
Owner
bot
Visibility
public
Status
active
Compatibility
backward
Decision
ADR-043
Schema
https://openvibe.network/contracts/bot/robot-profile.v1.json

bot.robot-profile@1 (ADR-043 decision 7): a robot profile as OpenVibe.Bot ships it (server/profiles/*.json) and serves it (GET /api/v1/profiles, /profiles/:id; validateProfile in server/profiles/index.js). The panel is a function of the profile. Capability and widget names are open strings that Bot checks against registries in code, so a new one never needs a schema change. As served, vendor, kind, description, variants and camera are null when the file leaves them out, limits carry their defaults (max_speed 1, max_turn 1, max_command_ms 300, heartbeat_ms 1000) and commands always include halt. mapping is the driver's own hardware map, open beyond driver.

Fields

FieldTypeRequiredDescriptionConstraints
idstringyes
  • pattern ^[a-z][a-z0-9._-]{1,63}$
versionintegeryes
  • minimum 1
namestringyes
  • minLength 1
vendorstring | null
kindenum
  • one of "onboard", "bridge", "server", null
descriptionstring | null
capabilitiesarray of stringyes
  • minItems 1
  • items: pattern ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)*$
variantsobject | null
mappingobjectyes
mapping.driverenumyes
  • one of "pca9685", "ads7830", "cozmo", "onvif", "sim"
mapping.pluginstring
commandsobject
  • no other fields
commands.driveobject
  • no other fields
commands.drive.axesobjectyes
  • no other fields
commands.drive.axes.throttlearray of number
  • minItems 2
  • maxItems 2
commands.drive.axes.steerarray of number
  • minItems 2
  • maxItems 2
commands.drive.axes.xarray of number
  • minItems 2
  • maxItems 2
commands.drive.axes.yarray of number
  • minItems 2
  • maxItems 2
commands.drive.axes.rotationarray of number
  • minItems 2
  • maxItems 2
commands.ptzobject
  • no other fields
commands.ptz.axesobjectyes
  • no other fields
commands.ptz.axes.panarray of number
  • minItems 2
  • maxItems 2
commands.ptz.axes.tiltarray of number
  • minItems 2
  • maxItems 2
commands.ptz.axes.zoomarray of number
  • minItems 2
  • maxItems 2
commands.actuatorobject
  • no other fields
commands.actuator.namesobjectyes
commands.sayobject
  • no other fields
commands.say.max_charsinteger
  • minimum 1
commands.displayobject
  • no other fields
commands.display.modesarray of enumyes
  • minItems 1
  • items: one of "text", "face", "image_png_b64"
commands.display.facesarray of string
  • items: pattern ^[a-z][a-z0-9_]{0,23}$
commands.display.max_charsinteger
  • minimum 1
commands.haltobject
  • no other fields
widgetsarray of objectyes
  • minItems 1
  • items: no other fields
widgets[].typestringyes
  • pattern ^[a-z][a-z0-9-]*$
widgets[].capabilitystring
widgets[].labelstring
  • maxLength 60
widgets[].orderinteger
widgets[].commandobject
  • no other fields
widgets[].command.kindenumyes
  • one of "drive", "actuator", "ptz", "say", "display", "halt"
widgets[].command.namesarray of string
  • minItems 1
  • items: pattern ^[a-z][a-z0-9_]{0,23}$
cameraobject | null
limitsobject
  • no other fields
limits.max_speednumber
limits.max_turnnumber
limits.max_command_msinteger
  • minimum 1
limits.heartbeat_msinteger
  • minimum 1

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: adeept-file
{
  "id": "adeept.adr036",
  "version": 1,
  "name": "Adeept ADR036 4WD Smart Car",
  "vendor": "Adeept",
  "kind": "onboard",
  "capabilities": [
    "drive.differential",
    "servo.pan_tilt",
    "lights.rgb",
    "speaker.horn",
    "sensor.ultrasonic",
    "battery"
  ],
  "mapping": {
    "driver": "pca9685",
    "plugin": "adeept_adr036",
    "wheels": "ordinary",
    "i2c_bus": 1,
    "address": "0x5f",
    "motor_channels": [
      8,
      9,
      10,
      11,
      12,
      13,
      14,
      15
    ],
    "servo_channels": {
      "pan": 0,
      "tilt": 1
    },
    "battery": {
      "driver": "ads7830",
      "address": "0x48"
    },
    "lights": "ws2812",
    "horn": "buzzer"
  },
  "commands": {
    "drive": {
      "axes": {
        "throttle": [
          -1,
          1
        ],
        "steer": [
          -1,
          1
        ]
      }
    },
    "actuator": {
      "names": {
        "pan": {
          "type": "number",
          "range": [
            -1,
            1
          ]
        },
        "tilt": {
          "type": "number",
          "range": [
            -1,
            1
          ]
        },
        "buzzer": {
          "type": "tone",
          "hz": [
            220,
            880
          ]
        },
        "lights": {
          "type": "rgb",
          "count": 8
        }
      }
    }
  },
  "widgets": [
    {
      "type": "drive",
      "capability": "drive.differential",
      "label": "Drive",
      "order": 1,
      "command": {
        "kind": "drive"
      }
    },
    {
      "type": "pan-tilt",
      "capability": "servo.pan_tilt",
      "label": "Pan / tilt",
      "order": 2,
      "command": {
        "kind": "actuator",
        "names": [
          "pan",
          "tilt"
        ]
      }
    },
    {
      "type": "battery",
      "capability": "battery",
      "label": "Battery",
      "order": 3
    },
    {
      "type": "latency",
      "label": "Latency",
      "order": 4
    }
  ],
  "camera": {
    "transport": "whip",
    "resolution": "640x480"
  },
  "limits": {
    "max_speed": 1,
    "max_turn": 1,
    "max_command_ms": 300,
    "heartbeat_ms": 1000
  }
}
Valid: sim-served
{
  "id": "sim.rover",
  "version": 1,
  "name": "Simulated rover",
  "vendor": null,
  "kind": "server",
  "description": null,
  "capabilities": [
    "drive.differential",
    "camera"
  ],
  "variants": null,
  "mapping": {
    "driver": "sim"
  },
  "commands": {
    "drive": {
      "axes": {
        "throttle": [
          -1,
          1
        ],
        "steer": [
          -1,
          1
        ]
      }
    },
    "say": {
      "max_chars": 200
    },
    "halt": {}
  },
  "widgets": [
    {
      "type": "drive",
      "capability": "drive.differential",
      "label": "Drive",
      "order": 1,
      "command": {
        "kind": "drive"
      }
    },
    {
      "type": "camera",
      "capability": "camera",
      "order": 2
    }
  ],
  "camera": null,
  "limits": {
    "max_speed": 1,
    "max_turn": 1,
    "max_command_ms": 300,
    "heartbeat_ms": 1000
  }
}
Rejected: unknown-command-kind
{
  "id": "adeept.adr036",
  "version": 1,
  "name": "Adeept ADR036 4WD Smart Car",
  "vendor": "Adeept",
  "kind": "onboard",
  "capabilities": [
    "drive.differential",
    "servo.pan_tilt",
    "lights.rgb",
    "speaker.horn",
    "sensor.ultrasonic",
    "battery"
  ],
  "mapping": {
    "driver": "pca9685",
    "plugin": "adeept_adr036",
    "wheels": "ordinary",
    "i2c_bus": 1,
    "address": "0x5f",
    "motor_channels": [
      8,
      9,
      10,
      11,
      12,
      13,
      14,
      15
    ],
    "servo_channels": {
      "pan": 0,
      "tilt": 1
    },
    "battery": {
      "driver": "ads7830",
      "address": "0x48"
    },
    "lights": "ws2812",
    "horn": "buzzer"
  },
  "commands": {
    "fly": {}
  },
  "widgets": [
    {
      "type": "drive",
      "capability": "drive.differential",
      "label": "Drive",
      "order": 1,
      "command": {
        "kind": "drive"
      }
    },
    {
      "type": "pan-tilt",
      "capability": "servo.pan_tilt",
      "label": "Pan / tilt",
      "order": 2,
      "command": {
        "kind": "actuator",
        "names": [
          "pan",
          "tilt"
        ]
      }
    },
    {
      "type": "battery",
      "capability": "battery",
      "label": "Battery",
      "order": 3
    },
    {
      "type": "latency",
      "label": "Latency",
      "order": 4
    }
  ],
  "camera": {
    "transport": "whip",
    "resolution": "640x480"
  },
  "limits": {
    "max_speed": 1,
    "max_turn": 1,
    "max_command_ms": 300,
    "heartbeat_ms": 1000
  }
}
Rejected: unknown-driver
{
  "id": "adeept.adr036",
  "version": 1,
  "name": "Adeept ADR036 4WD Smart Car",
  "vendor": "Adeept",
  "kind": "onboard",
  "capabilities": [
    "drive.differential",
    "servo.pan_tilt",
    "lights.rgb",
    "speaker.horn",
    "sensor.ultrasonic",
    "battery"
  ],
  "mapping": {
    "driver": "arduino"
  },
  "commands": {
    "drive": {
      "axes": {
        "throttle": [
          -1,
          1
        ],
        "steer": [
          -1,
          1
        ]
      }
    },
    "actuator": {
      "names": {
        "pan": {
          "type": "number",
          "range": [
            -1,
            1
          ]
        },
        "tilt": {
          "type": "number",
          "range": [
            -1,
            1
          ]
        },
        "buzzer": {
          "type": "tone",
          "hz": [
            220,
            880
          ]
        },
        "lights": {
          "type": "rgb",
          "count": 8
        }
      }
    }
  },
  "widgets": [
    {
      "type": "drive",
      "capability": "drive.differential",
      "label": "Drive",
      "order": 1,
      "command": {
        "kind": "drive"
      }
    },
    {
      "type": "pan-tilt",
      "capability": "servo.pan_tilt",
      "label": "Pan / tilt",
      "order": 2,
      "command": {
        "kind": "actuator",
        "names": [
          "pan",
          "tilt"
        ]
      }
    },
    {
      "type": "battery",
      "capability": "battery",
      "label": "Battery",
      "order": 3
    },
    {
      "type": "latency",
      "label": "Latency",
      "order": 4
    }
  ],
  "camera": {
    "transport": "whip",
    "resolution": "640x480"
  },
  "limits": {
    "max_speed": 1,
    "max_turn": 1,
    "max_command_ms": 300,
    "heartbeat_ms": 1000
  }
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('bot.robot-profile@1', value);   // { valid, errors: [{ path, message }] }