Kinect Xbox 360 Depth Mapping icon Kinect Xbox 360 Depth Mapping — Converts Xbox 360 Kinect depth frames into NMS obstacle scans for ARC path planning, SLAM, and obstacle avoidance. Try it →
 
Key Control Robot Skill

Key Control

by Synthiam Inc.

Browser-based keyboard robot control with remappable keys for driving, servo control, speed changes, scripts, and safe deadman stopping.

Requires ARCx v1 (Updated 10/19/2026)
Tags: Remote Control Scripting Servo
Compatible with: Compatible with Microsoft Windows 10 or 11 Windows Compatible with ARM Linux (Raspberry pi, etc) ARM Compatible with Linux Linux Compatible with MacOS MacOS

How to add the Key Control robot skill

  1. Load the most recent release of ARCx on a compatible operating system (Get ARCx).
  2. Press the + Skills menu from the top menu bar in ARCx.
  3. Choose any of these category tabs, the robot skill appears in each of them: Remote Control, Scripting, Servo.
  4. Press the Key Control icon to add the robot skill to your project.

Don't have a robot yet?

Follow the Getting Started Guide to build a robot and use the Key Control robot skill.


How to use the Key Control robot skill

Key Control drives your robot from a keyboard. Hold the arrow keys and the robot drives through whichever Movement Panel the project has; let go and it stops. Every key can be remapped, and each one can drive in a direction, change the speed, nudge a servo, move a servo to a position, disarm the keyboard or simply run a script when it goes down and another when it comes up.

ARCx runs in a web browser, so the keys are read in the browser you are typing into: the computer on the robot, a laptop across the room, a tablet, or a Custom UI kiosk with a keyboard plugged in. Nothing has to be installed on the robot's computer to read the keyboard, and it works the same on Windows, Linux and macOS.

The window

Key Control window

The bar along the top has the Armed button, the page-wide capture button, the movement speed with - and + buttons, and what the Movement Panel is doing right now.

Below it is the keyboard pad. Click it and its border turns green with Keyboard active: from then on the bound keys drive the robot. Click anywhere else, switch to another window or hide the browser tab and every held key is released, which stops the robot. This is the same "click here to activate" box ARC had.

The key map inside the pad has a tile for every binding, showing the key and what it does. The arrow keys are laid out as an inverted T. A tile lights up while its key is held, from this browser, another browser or a script, and the keys held right now are listed on the right of the pad. Tiles can also be held down with the mouse or a finger, so a phone without a keyboard still makes a usable remote.

The log at the bottom shows each key going down and up, why keys were released (focus lost, watchdog, disarmed) and anything the key scripts print.

Arming and safety

Keys only do something while the keyboard is armed. Disarming releases every held key and, with Stop On Disarm, stops the robot. Arm and disarm from the window, the Custom UI widget, a script (controlCommand("Key Control", "Disarm")) or an AI. Disarm before an autonomous routine so nobody's keyboard interferes with it, and bind a panic key (Escape, say) to Disarm the keyboard.

Movement keys are a deadman by default: the robot moves only while the key is held. Hold Up and tap Left, and when Left is released the robot carries on forward (Resume Held Direction). Several things release held keys for you:

  • The pad loses focus (unless page-wide capture is on), the browser window loses focus, the tab is hidden or the page is closed.
  • The watchdog: a browser holding a key reports in four times a second. If it goes quiet for longer than the watchdog time (Wi-Fi drops, a phone locks, the browser crashes) its keys are released and the robot stops.
  • The configuration page is opened, the configuration changes, or the panic button is pressed.

The browser's own key repeat is ignored, so holding a key is one press however long it is held. Keys that repeat on purpose (servo nudges, speed up and down) repeat at their own rate.

Page-wide capture

With Capture Page-Wide on, an armed Key Control also reads keys pressed anywhere on the ARCx page that shows it, not only in the pad, so you can drive while looking at a camera on the same workspace. Typing in a text field, a dropdown, a slider or a script editor is left alone, and only bound keys are taken from the page. Turn it on and off with the button in the window's bar or the SetCapturePageWide control command.

Custom UI widget

The Keyboard drive pad widget puts the pad, the key map and the Armed button on a Custom UI screen. It captures keys anywhere on the screen while armed, which suits a kiosk with a keyboard plugged in: open the screen and drive, no clicking first. On a phone the tiles are big enough to hold with a finger.

Keyboard drive pad widget on a Custom UI screen

Keyboard drive pad widget in the Custom UI designer

Setting What it does
Caption The title above the pad
CapturePageWide true (default): listen to keys anywhere on the screen while armed. false: only after the pad is tapped
ShowKeyMap Show the key tiles
ShowArmButton Show the Armed / Disarmed button

Custom UI labels can show the keys too, for example Holding: {KeyControlKeysHeld}.

Configuration

The configuration page lists the options and every binding on the left. Pick one to edit it on the right. Add makes a new binding and the gamepad button adds the arrow keys, Space and the speed keys for any of them that are not bound yet.

Bindings

A movement key binding

Press Set key (or Change key) and then press the key, or the combination with Ctrl, Alt, Shift or Meta held. A modifier on its own, such as Left Shift, can be a key too: press and release it by itself. You can also type the key into Key code: W, Up, Space, Num8, F5, Ctrl+G, or a browser code such as KeyW. Keys are stored by their position on the keyboard, so a binding works the same on any keyboard layout. A combination must match exactly: Shift+Up and Up are different bindings, which makes Shift+Up a handy turbo.

Waiting for a key to be pressed

Action What the key does
Scripts only Nothing of its own; only its key down and key up scripts run
Drive in a direction Forward, Reverse, Left, Right (and Up, Down, Roll, Take off, Land for flying robots). Speed 0 uses the current speed, or set 1 to 255 for this key. Stop when released makes it a deadman; turn it off and the key latches until a stop
Stop moving Stops the robot and forgets any movement keys still held
Speed up / Slow down Changes the speed by the step, repeating while held when Repeat every is above 0
Set the speed Sets the speed, for gear keys such as 1, 2 and 3
Nudge a servo Moves the servo (or several together) by the step, repeating while held. Bind a second key with the opposite step
Move a servo to a position Moves the servo when pressed, and to the release position when let go (0 stays put): hold G to open a gripper, let go to close it
Disarm the keyboard A panic key

A <a href='/Support/Advanced-Fundamentals/servo-motor' target='_top'>servo</a> binding

A scripts-only binding

Every binding has a Key down script, which runs once when the key is pressed, and a Key up script, which runs when it is released or released for it. The two share one script runner, so the key up script stops a key down script that is still running. An optional Name is shown on the tile instead of the action. A binding with a warning symbol in the list has a problem, such as a key that is already bound above it.

Options

Options

Setting What it does
Armed At Start Arm the keyboard when the project loads
Capture Page-Wide Read keys anywhere on the page while armed, not only in the pad
Resume Held Direction Releasing the newest of two held movement keys resumes the other one instead of stopping
Stop On Disarm Stop the robot whenever the keyboard is disarmed
Watchdog How long a browser holding a key may go quiet before its keys are released, 300 to 10000 ms
Repeat Delay How long a repeating key waits before it starts repeating
Show Key Map Show the key tiles in the window
Show Log Show the log in the window
Log Key Presses Write every bound key press and release to the log
Variable Prefix The start of the global variable names, for giving each Key Control in a project its own
Unbound Key Script Runs when an armed key with no binding is pressed

Variables

Variable Value
$KeyControlArmed true while the keys drive the robot
$KeyControlLastKey The last key pressed or released, as people write it (Ctrl+W, ``)
$KeyControlLastKeyCode Its browser code (KeyW, ArrowUp)
$KeyControlLastKeyEvent Down or Up
$KeyControlKeysHeld The keys held right now, comma separated

The Unbound Key script can use them to handle many keys in one place:

var key = getVar("$KeyControlLastKey");

if (key == "P")
  Audio.say("Taking a picture");
else
  print("Nothing is bound to " + key);

Pressing keys from a script

Scripts and AI assistants can press the same keys, which is handy for testing a key map or replaying a sequence. These work even while the keyboard is disarmed, because they were asked for explicitly.

// Drive forward for one second, then stop
controlCommand("Key Control", "PressKey", "Up", 1000);

// Hold a key until told otherwise
controlCommand("Key Control", "KeyDown", "Q");
sleep(500);
controlCommand("Key Control", "KeyUp", "Q");

Reading keys on the robot's own keyboard

Key Control reads the keyboard through a browser. A keyboard plugged into the robot's computer works by showing ARCx (or a Custom UI screen with the Keyboard drive pad widget) in a browser on that computer, for example as a kiosk. Reading the keyboard behind the browser's back would need a different system hook on Windows, Linux and macOS, and permissions on each, so Key Control does not do it.


Control Commands for the Key Control robot skill

There are Control Commands available for this robot skill which allows the skill to be controlled programmatically from scripts or other robot skills. These commands enable you to automate actions, respond to sensor inputs, and integrate the robot skill with other systems or custom interfaces. If you're new to the concept of Control Commands, we have a comprehensive manual available here that explains how to use them, provides examples to get you started and make the most of this powerful feature.

Control Command Manual

This robot skill has 11 control commands, listed below. Send them from a JavaScript or Python script, from Blockly, or from another robot skill.

The first value is always the window title, which is the name in the title bar of the robot skill on your workspace. It starts out as Key Control, which is what every example below uses. If you rename the robot skill, or add a second copy of it to the project, use the title as it appears on that window instead.

ControlCommand() can be shortened to CC(), and both spellings work in JavaScript and in Python. The examples are JavaScript; Python is the same call, except that true and false are written True and False.

Arm

Arm the keyboard: keys pressed in the Key Control pad (or anywhere on the page with page-wide capture) drive the robot and run their scripts. Returns true.

Syntax

ControlCommand("Key Control", "Arm")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "Arm");

Disarm

Disarm the keyboard: every held key is released (stopping the robot) and keys do nothing until it is armed again. Use it before an autonomous routine so nobody's keyboard interferes. Returns false.

Syntax

ControlCommand("Key Control", "Disarm")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "Disarm");

GetBindings

Every enabled binding as "key = action" (" = Forward", "Ctrl+G = Open gripper").

Syntax

ControlCommand("Key Control", "GetBindings")

Returns: Array of String

Example

var result = ControlCommand("Key Control", "GetBindings");

GetHeldKeys

The keys held down right now, as people write them ("", "Ctrl+W").

Syntax

ControlCommand("Key Control", "GetHeldKeys")

Returns: Array of String

Example

var result = ControlCommand("Key Control", "GetHeldKeys");

IsArmed

Whether the keyboard is armed.

Syntax

ControlCommand("Key Control", "IsArmed")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "IsArmed");

KeyDown

Hold a key down until KeyUp (or ReleaseAll) releases it: a movement key keeps driving, a servo step key keeps stepping. Works while disarmed. Returns true when the key is bound.

Syntax

ControlCommand("Key Control", "KeyDown", (String)key)

Parameters

# Name Type What to pass
1 key Text Your text, in quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "KeyDown", "key");

KeyUp

Release a key held with KeyDown. Returns true.

Syntax

ControlCommand("Key Control", "KeyUp", (String)key)

Parameters

# Name Type What to pass
1 key Text Your text, in quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "KeyUp", "key");

PressKey

Press a key as if it were typed: its binding acts and its key down script runs, then after the duration it is released (a movement key stops, the key up script runs). Works while disarmed. The key is a name such as "Up", "W", "Ctrl+W", "Space", "F5", "Num8", or a browser code such as "ArrowUp" or "KeyW". The duration is in milliseconds (default 250, up to 60000). Returns true when the key is bound.

Syntax

ControlCommand("Key Control", "PressKey", (String)key, 250)

Parameters

# Name Type What to pass
1 key Text Your text, in quotes
2 durationMs Number The fixed value 250. Leave it as it is.

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "PressKey", "key", 250);

ReleaseAll

Release every held key from every browser and script, which stops a robot a key was driving. Returns how many keys were held.

Syntax

ControlCommand("Key Control", "ReleaseAll")

Returns: Integer [-2,147,483,648 to 2,147,483,647]

Example

var result = ControlCommand("Key Control", "ReleaseAll");

SetCapturePageWide

True: while armed, keys pressed anywhere on the page showing Key Control are captured (not while typing in a text field or script editor). False: only while the Key Control pad has focus. Saved with the project. Returns the new setting.

Syntax

ControlCommand("Key Control", "SetCapturePageWide", (Bool)pageWide)

Parameters

# Name Type What to pass
1 pageWide True or false true or false, without quotes

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "SetCapturePageWide", true);

ToggleArm

Arm the keyboard if it is disarmed, disarm it if it is armed. Returns the new state: true when armed.

Syntax

ControlCommand("Key Control", "ToggleArm")

Returns: Boolean [true or false]

Example

var result = ControlCommand("Key Control", "ToggleArm");

This list is read out of the robot skill itself each time its package is uploaded, so it matches the published version (v1).


ARC Pro

Upgrade to ARC Pro

ARC Pro is your passport to a world of endless possibilities in robot programming, waiting for you to explore.