Python library for communicating with Marty the Robot V1 and V2 by Robotical.
Reference version: MartyPy 3.8.0, checked against the published package on 7 October 2026. Signatures below match this version; where an annotation differs from the actual return value, the entry explains that difference.
MartyPy on PyPI · Source for this release
Install or update in the Python environment that will run your program:
python -m pip install --upgrade martypy
Getting started on a computer (replace the example IP address with Marty's actual address):
from martypy import Marty
my_marty = Marty("wifi", "192.168.0.53")
try:
my_marty.get_ready()
my_marty.dance()
finally:
my_marty.close()
The tags 1️⃣ and 2️⃣ indicate Marty V1 and Marty V2 support. Features also depend on the connected hardware, add-ons and firmware. Methods without a robot-version tag, such as translation and colour helpers, may operate on the computer rather than send a robot command.
Desktop Python and Blocks
This is the reference for the installed MartyPy package. Native Marty V2 connections use WiFi, USB or the expansion port; 'socket' is the legacy Marty V1 connection. A native MartyPy 'bluetooth' connection method is not provided by this release.
In Blocks, Python runs in the browser and supported Marty calls use the app's existing connection to the robot, including Bluetooth. The app supplies my_marty; do not copy desktop connection/installation code into its editor. Browser Python supports a selected set of Marty-style APIs, not every native MartyPy function. Browser speech uses browser audio support and does not require installing FFmpeg on your computer.
Speech and translation requirements
The speech and translation APIs use Robotical's online service, so internet access is needed. Text passed to these functions is sent to that service. Desktop speech needs FFmpeg; speak_on_computer also needs an audio playback backend such as ffplay. Translation and get_language do not require FFmpeg. Default speech settings are ALTO/FEMALE, English and speed 1, and persist on the Marty object until changed.
Waiting for sensor conditions
The foot_on_ground and foot_obstacle_sensed methods return Python Booleans: use True/False, not the strings 'true'/'false'. Sensor getters normally read the latest received telemetry rather than performing a fresh blocking measurement. Missing or stale telemetry can produce empty/zero readings; a missing foot sensor can raise MartyCommandException.
Put subsequent movement after the wait loop, not inside it. Include a short sleep and a timeout so the loop does not spin indefinitely:
import time
from martypy import Marty
my_marty = Marty("wifi", "192.168.0.53")
try:
my_marty.get_ready()
deadline = time.monotonic() + 15
while not my_marty.foot_obstacle_sensed("right"):
if time.monotonic() >= deadline:
raise TimeoutError("No obstacle detected within 15 seconds")
time.sleep(0.05)
my_marty.kick("right")
finally:
my_marty.close()
Support Marty safely with clear space around it when testing movements. Check Boolean command results and catch/report exceptions where appropriate: a generated command or accepted request is not by itself proof that the robot completed the movement.
Call methods on your connected Marty instance, for example my_marty.walk(num_steps=10). In signatures, Optional means a value may be None, and Union means more than one input type is accepted. Marty.Disco group constants are written as Disco in the signatures.
__init__(method: str, locator: str = "", extra_client_types: dict = dict(), blocking: Union[bool, None] = None, *args, **kwargs) -> None
Start a connection to Marty 1️⃣ 2️⃣
For example:
Blocking Mode
Movement commands that expose a blocking argument (e.g. walk(), dance(), move_joint(), but also hold_position()) comes with two modes - blocking and non-blocking.
Issuing a command in blocking mode will make your program pause until Marty physically stops moving. Only then the next line of your code will be executed.
In non-blocking mode, each movement command simply tells Marty what to do and returns immediately, meaning that your code will continue to execute while Marty is moving.
Movement methods whose signatures include blocking take an optional blocking argument that can be used to choose the mode for that call. If you plan to use the same mode all or most of the time, you can use the Marty.set_blocking() method or use the blocking constructor argument. The latter defaults to True (blocking) if not provided.
Arguments:
Raises:
is_conn_ready() -> bool
Check if the robot is connected and the connection is ready to accept commands 2️⃣
Arguments:
None
Returns:
True if the robot is connected and ready
is_blocking() -> bool
Check the default movement command behaviour of this Marty. 1️⃣ 2️⃣
Returns:
True if movement commands block by default
set_blocking(blocking: bool)
Change whether movement commands default to blocking or non-blocking behaviour for this Marty. 1️⃣ 2️⃣
The blocking behaviour can also be specified on a per-command basis using the blocking= argument which takes precedence over Marty's overall setting.
Arguments:
close() -> None
Close the connection to Marty. Call this explicitly in a finally block when a desktop program ends. Closing the connection is not a replacement for intentionally stopping movement with stop.
get_ready(blocking: Optional[bool] = None) -> bool
Move Marty to the normal standing position and wiggle eyebrows 1️⃣ 2️⃣ Will also enable motors for Marty v1 1️⃣
Arguments:
Returns:
True if Marty accepted the request
stand_straight(move_time: int = 2000, blocking: Optional[bool] = None) -> bool
Move Marty to the normal standing position 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
walk(num_steps: int = 2, start_foot: str = 'auto', turn: int = 0, step_length: int = 25, move_time: int = 1500, blocking: Optional[bool] = None) -> bool
Make Marty walk 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
sidestep(side: str, steps: int = 1, step_length: int = 35, move_time: int = 1000, blocking: Optional[bool] = None) -> bool
Take sidesteps 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
lift_foot(side: str) -> bool
Lift a foot. 2️⃣
Returns True if Marty accepts the request. This method has no blocking argument and does not wait for the movement to finish.
lower_foot(side: str) -> bool
Lower a foot. 2️⃣
Returns True if Marty accepts the request. This method has no blocking argument and does not wait for the movement to finish.
wave(side: str) -> bool
Wave an arm. 2️⃣
Returns True if Marty accepts the request. This method has no blocking argument and does not wait for the movement to finish.
dance(side: str = 'right', move_time: int = 3000, blocking: Optional[bool] = None) -> bool
Boogie, Marty! 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
celebrate(move_time: int = 4000, blocking: Optional[bool] = None) -> bool
Celebrate. 1️⃣ 2️⃣ On Marty V2 this currently uses the wiggle trajectory.
Arguments:
Returns:
True if Marty accepted the request
wiggle(move_time: int = 4000, blocking: Optional[bool] = None) -> bool
Wiggle. 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
circle_dance(side: str = 'right', move_time: int = 2500, blocking: Optional[bool] = None) -> bool
Circle dance. 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
eyes(pose_or_angle: Union[str, int], move_time: int = 1000, blocking: Optional[bool] = None) -> bool
Move the eyes to a pose or an angle 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
kick(side: str = 'right', twist: int = 0, move_time: int = 2500, blocking: Optional[bool] = None) -> bool
Kick one of Marty's feet 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
arms(left_angle: int, right_angle: int, move_time: int, blocking: Optional[bool] = None) -> bool
Move both of Marty's arms to angles you specify 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
lean(direction: str, amount: Optional[int] = None, move_time: int = 1000, blocking: Optional[bool] = None) -> bool
Lean over in a direction 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
move_joint(joint_name_or_num: Union[int, str], position: int, move_time: int, blocking: Optional[bool] = None) -> bool
Move a specific joint to a position 1️⃣ 2️⃣
Arguments:
Returns:
True if Marty accepted the request
Raises:
MartyCommandException if the joint_name_or_num is unknown
hold_position(hold_time: int, blocking: Optional[bool] = None) -> bool
Hold Marty at its current position 2️⃣
Arguments:
hold_time, time to hold position in milli-seconds - blocking - Blocking mode override; whether to wait for physical movement to finish before returning. Defaults to the value returned by self.is_blocking(). Holding position counts as movement because Marty is using its motors to actively resist any attempts to move its joints.
Returns:
True if Marty accepted the request
is_moving() -> bool
Check if Marty is moving 2️⃣
Arguments:
none
Returns:
True if Marty is moving
is_paused() -> bool
Check if Marty is paused 2️⃣
Returns:
True if Marty is paused
stop(stop_type: Optional[str] = None) -> bool
Stop Marty's movement 1️⃣ 2️⃣
You can also control what way to “stop” you want with the parameter stop_type. For instance:
Arguments:
Raises:
MartyCommandException if the stop_type is unknown
With stop_type omitted, this uses 'clear and stop'. Pass the string name, not a numeric stop code. Returns True if the stop request succeeds.
resume() -> bool
Resume Marty's movement after a pause 2️⃣
Returns:
True if Marty accepted the request
set_volume(volume: int) -> bool
Set Marty's speaker volume. 2️⃣
Returns True if Marty accepts the request. This does not change the computer speaker volume.
get_volume() -> int
Read Marty's speaker volume (0 to 100). 2️⃣
play_sound(name_or_freq_start: Union[str,int], freq_end: Optional[int] = None, duration: Optional[int] = None) -> bool
Play a named sound (Marty V2 2️⃣) or make a tone (Marty V1 1️⃣)
Arguments:
Returns:
True if Marty accepted the request
play_mp3(filename: str, progress_callback: Callable[[int, int], bool] = None) -> bool
Stream an MP3 file from the computer to Marty's speaker. 2️⃣
Returns True if streaming succeeds. This method has no blocking argument; it waits for the streaming operation, not a separate movement-completion wait. File, connection and streaming failures may return False or raise exceptions.
set_voice(voice: str)
Set the default voice for subsequent calls to speak and speak_on_computer. Available from MartyPy 3.8.0.
Arguments:
Other supported names are ALTO, TENOR, THUNDER, STONE, RUMBLE, ECHO, DRIFT, BREEZE, WAVE, BLAZE, MIST, DAWN, CRYSTAL, LULLABY, AURORA, RADIANCE and FLASH. KITTEN produces meows rather than spoken words.
The initial voice is ALTO (FEMALE). Returns None. An unknown voice raises ValueError.
set_voice_speed(speed: float)
Set the default speed for subsequent speech. Available from MartyPy 3.8.0.
Arguments:
Returns None. Invalid or non-finite speeds raise ValueError. Desktop MartyPy changes playback rate, which can also change pitch.
set_speech_language(language: str)
Set the language/accent used for subsequent speech synthesis. Available from MartyPy 3.8.0. This does not translate the words.
Arguments:
The initial language is English (en). Supported speech codes are ar, zh-cn, da, nl, en, fr, de, hi, is, it, ja, ko, nb, pl, pt-br, pt, ro, ru, es, es-419, sv, tr and cy.
Returns None. An unsupported speech language raises ValueError. Translation supports additional languages; a language accepted by translate is not necessarily supported for speech.
speak(words: str = 'hello', voice: Optional[str] = None, blocking: Optional[bool] = False, language: Optional[str] = None, speed: Optional[float] = None) -> bool
Speak through Marty's speaker. 2️⃣
Arguments:
Returns:
True if the audio stream was accepted; False if streaming failed. Explicit voice, language and speed values apply to this call without changing the saved defaults. Language and speed overrides and saved speech settings are available from MartyPy 3.8.0.
Desktop MartyPy requires internet access and FFmpeg. Audio is generated using Robotical's online service, processed on the computer and streamed to Marty. Network, synthesis, audio-processing and connection errors may raise exceptions.
my_marty.set_voice("FEMALE")
my_marty.set_voice_speed(1.2)
my_marty.speak("Hello from Marty", blocking=True)
speak_on_computer(words: str = 'hello', voice: Optional[str] = None, language: Optional[str] = None, speed: Optional[float] = None) -> bool
Speak through the computer's speakers, not Marty's. Available from MartyPy 3.8.0.
Arguments:
Returns:
True after computer playback finishes. This call waits and has no blocking argument. It does not send an audio command to Marty. Desktop use requires internet, FFmpeg and a supported playback backend such as ffplay. Invalid settings or network/audio failures can raise exceptions. In Blocks, browser audio is used instead and FFmpeg is not required.
translate(words: str, language: str) -> str
Translate text using Robotical's online service. Available from MartyPy 3.8.0. Internet access is required; no robot command is sent.
Arguments:
Returns:
The translated text as a string. Empty text and text consisting only of digits are returned unchanged. This function does not speak, change the speech accent or change the selected speech language.
Malformed service responses raise ValueError; network and HTTP failures raise exceptions rather than being reported as successful translations.
my_marty.set_speech_language("fr")
translated = my_marty.translate("Hello", "fr")
my_marty.speak(translated, blocking=True)
get_language() -> str
Return the computer's configured locale language. Available from MartyPy 3.8.0.
For a recognised locale, the result is a language name such as English or French; otherwise it is the normalised locale code. If the locale is unavailable, English is used. This does not read a language setting from Marty and does not report the current speech language.
In Blocks, the corresponding function reports the editor language instead of the desktop Python locale.
get_accelerometer(axis: Optional[str] = None) -> float
Read the latest accelerometer telemetry. 1️⃣ 2️⃣
Actual return value:
With an axis, returns that acceleration reading. On V2 without an axis, returns a three-value sequence [x, y, z] (a list for normal telemetry, or (0, 0, 0) before any telemetry arrives), despite the float annotation. Individual-axis reads return 0 when data is unavailable or stale. An unknown axis raises MartyCommandException.
get_distance_sensor() -> Union[int, float]
Get the latest value from the distance sensor 1️⃣ 2️⃣
Returns:
The distance sensor reading. The meaning of the returned value is different between Marty V1 and V2:
foot_on_ground(add_on_or_side: str) -> bool
Checks whether the foot is on a surface 2️⃣
Arguments:
Returns:
A boolean for whether the addon detects the ground. True for ground detected, False otherwise.
Returns a Python Boolean, not a 'true'/'false' string.
foot_obstacle_sensed(add_on_or_side: str) -> bool
Checks whether there is an obstacle in front of the foot 2️⃣
Arguments:
Returns:
A boolean for whether the addon detects an obstacle. True for obstacle detected, False otherwise.
This returns a Python Boolean, not the text 'true'/'false'. Use the value directly in conditions.
get_obstacle_sensor_reading(add_on_or_side: str) -> int
Gets a raw obstacle sensor reading from an IR or color sensor 2️⃣
Arguments:
Returns:
Raw reading of obstacle sensor data from the add on.
get_ground_sensor_reading(add_on_or_side: str) -> int
Gets a raw ground sensor reading from an IR or color sensor 2️⃣
Arguments:
Returns:
Raw reading of ground sensor data from the add on.
get_color_sensor_color(add_on_or_side: str) -> int
Read the colour classification from a colour sensor. 2️⃣
Actual return value:
A string: yellow, green, blue, purple, red, air or unclear. 'air' means the sensor does not detect the ground; 'unclear' means the colour cannot be classified. If there is no current sensor data, 0 can be returned. A missing or invalid sensor can raise MartyCommandException.
The published 3.8.0 annotation says int, but a successful colour classification is a string, not an integer.
get_color_sensor_hex(add_on_or_side: str) -> str
Read a colour sensor's RGB channels as a hexadecimal colour string, without a leading #. 2️⃣
If there is no current sensor data, 0 can be returned despite the str annotation. A missing or invalid sensor can raise MartyCommandException.
get_color_sensor_value_by_channel(add_on_or_side: str, channel: str) -> int
Read a raw channel from a colour sensor. 2️⃣
Returns the channel reading, or 0 if no current data is available. Invalid channels or missing/invalid sensors can raise MartyCommandException.
get_joint_position(joint_name_or_num: Union[int, str]) -> float
Get the position (angle in degrees) of a joint 2️⃣
Arguments:
Returns:
Angle of the joint in degrees
Raises:
MartyCommandException if the joint_name_or_num is unknown
get_joint_current(joint_name_or_num: Union[int, str]) -> float
Get the current (in milli-Amps) of a joint 1️⃣ 2️⃣ This can be useful in detecting when the joint is working hard and is related to the force which the joint's motor is exerting to stay where it is
Arguments:
Returns:
the current of the joint in milli-Amps (this will be 0 if the joint current is unknown)
Raises:
MartyCommandException if the joint_name_or_num is unknown
get_joint_status(joint_name_or_num: Union[int, str]) -> int
Get information about a joint 2️⃣ This can be helpful to find out if the joint is working correctly and if it is moving at the moment, etc
Arguments:
Returns:
a code number which is the sum of codes in the Marty.JOINT_STATUS dictionary will be 0 if the joint status is unknown
Raises:
MartyCommandException if the joint_name_or_num is unknown
get_motor_current(motor_id: int) -> float
Get current flowing through a joint motor 1️⃣ 2️⃣
Arguments:
motor_id, integer >= 0 (non-negative) selects which motor to query
Returns:
Instantaneous current sense reading from motor motor_id
get_battery_remaining() -> float
Get the battery remaining percentage 2️⃣
Returns:
The battery remaining capacity in percent
get_robot_status() -> Dict
Read the latest robot-status telemetry. 2️⃣ The dictionary can be empty when telemetry is unavailable or stale.
Typical keys are:
Additional fields such as heapFree, heapMin, pixRGBT, loopMsAvg and loopMsMax depend on the status packet/firmware.
get_joints() -> Dict
Read the latest telemetry for Marty's joints. 2️⃣ Returns a dictionary keyed by joint ID, or an empty dictionary if telemetry is unavailable/stale.
Each joint entry can contain:
get_power_status() -> Dict
Read the latest battery/power telemetry. 2️⃣ Returns an empty dictionary if telemetry is unavailable/stale.
Possible keys include:
Fields may be omitted when the corresponding information is not valid or not reported.
get_add_ons_status() -> Dict
Read the latest add-on telemetry. 2️⃣ Returns a dictionary keyed by add-on ID, with an additional top-level updateTime entry. It can be empty if telemetry is unavailable/stale.
Add-on entries can include IDNo, name, type, whoAmI, whoAmITypeCode, valid and data (10 raw bytes whose meaning depends on the add-on).
When iterating over values, filter out non-dictionary entries such as updateTime:
for add_on_id, status in my_marty.get_add_ons_status().items():
if isinstance(status, dict):
print(add_on_id, status.get("name"), status.get("whoAmI"))
get_add_on_status(add_on_name_or_id: Union[int, str]) -> Dict
Read the latest status for one add-on. 2️⃣
Returns a dictionary with IDNo, valid and raw data, plus available hardware metadata such as name, type, whoAmI and whoAmITypeCode. Returns an empty dictionary when no matching current status is available.
get_system_info() -> Dict
Read cached firmware/hardware identification information. 2️⃣
The returned dictionary can include:
Available fields depend on the firmware. The Marty V1 client returns legacy placeholder identification values; use get_firmware_version/get_chatter for V1 firmware reporting.
get_hw_elems_list() -> List
Get a list of all of the hardware elements on Marty 2️⃣
Arguments:
none
Returns:
List containing a dictionary for each hardware element, each element is in the form:
set_marty_name(name: str) -> bool
Set Marty's name 2️⃣
Arguments:
name to call Marty
Returns:
True if successful in setting the name
get_marty_name() -> str
Get Marty's name 2️⃣
Arguments:
none
Returns:
the name given to Marty
is_marty_name_set() -> bool
Check if Marty's name is set 2️⃣
Arguments:
none
Returns:
True if Marty's name is set
is_calibrated() -> bool
Check if Marty is calibrated 2️⃣
save_calibration() -> bool
Set the current motor positions as the zero positions 1️⃣ 2️⃣
BE CAREFUL, this can cause unexpected movement or self-interference
clear_calibration() -> bool
Mark the current calibration as invalid 1️⃣ 2️⃣
This has no immediate physical effect. Marty will still remember the last calibration but will report that it needs to be calibrated again. (You may notice that a “Calibrate” button appears in the app for example.)
disco_off(add_on: Union[Disco, str] = Disco.ALL, api='led') -> bool
Turn off a Disco add-on or group. 2️⃣
Returns True if the requests succeed.
disco_pattern(pattern: int, add_on: Union[Disco, str] = Disco.ALL) -> bool
Deprecated: use disco_named_pattern for named firmware LED patterns. 2️⃣
Returns True if the requests succeed. Other pattern numbers raise an exception.
disco_named_pattern(add_on: str, pattern: str) -> bool
Run a named light pattern on a Disco add-on. 2️⃣ Preferred over the deprecated disco_pattern method.
Returns True if the request is accepted. An unknown pattern raises MartyCommandException.
my_marty.disco_named_pattern("LEDeye", "pinwheel")
disco_color(color: Union[str, Tuple[int, int, int]] = 'white', add_on: Union[Disco, str] = Disco.ALL, region: Union[int, str] = 'all', api='led') -> bool
Set the colour of a Disco add-on or group. 2️⃣
Returns True if the requests succeed. Use one of the two supported api values; other values do not select a valid operation.
my_marty.disco_color((255, 0, 12), add_on="LEDeye")
my_marty.disco_color("blue", add_on=Marty.Disco.EYES)
disco_color_specific_led(color: Union[str, Tuple[int, int, int]], add_on: str, add_on_who_am_i: str, led_id: int) -> bool
Set one LED on a Disco add-on. 2️⃣
Returns True if Marty accepts the request. Use get_hw_elems_list to inspect hardware metadata.
disco_color_eyepicker(colours: Union[str, List[str]], add_on: str) -> bool
Set individual colours for Disco eyes. 2️⃣
Returns True if Marty accepts the request.
rgb_operator(r: int, g: int, b: int) -> list[int]
Create an RGB colour from red, green and blue channel values. Use values from 0 to 255 for LED commands.
Actual return value: the tuple (r, g, b), not a list. The list[int] annotation in MartyPy 3.8.0 is inaccurate. The function does not send a robot command or validate/clamp the input.
hsv_operator(h: int, s: int, v: int) -> list[int]
Convert HSV (hue, saturation, value) to an RGB list. This is HSV, not HSL.
Saturation and value are clamped to 0–1 after conversion. Returns [red, green, blue] with integer channels from 0 to 255. Convert to a tuple when passing to disco_color, whose RGB input is a tuple.
colour = tuple(my_marty.hsv_operator(120, 100, 100))
my_marty.disco_color(colour, add_on="LEDeye")
function_led(colour: Tuple[int, int, int], breathe: str = 'on', breath_ms: int = 1000) -> bool
Set Marty's function/indicator LED, not a Disco add-on. 2️⃣
Returns True if Marty accepts the request. A colour with other than three channels raises MartyCommandException.
function_led_off() -> bool
Turn off Marty's function/indicator LED. 2️⃣ Returns True if Marty accepts the request.
add_on_query(add_on_name: str, data_to_write: bytes, num_bytes_to_read: int) -> Dict
Write and read an add-on directly (raw-mode) 2️⃣
Arguments:
Returns:
Dict with keys including: “rslt” - the result which will be “ok” if the query succeeded “dataRead” - the data read from the add-on
send_ric_rest_cmd(ricRestCmd: str) -> None
Send a command in RIC REST format to Marty 2️⃣
This is a special purpose command which you can use to do advanced control of Marty
Arguments:
Returns:
None
send_ric_rest_cmd_sync(ricRestCmd: str) -> Dict
Send a command in RIC REST format to Marty and wait for reply 2️⃣
This is a special purpose command which you can use to do advanced control of Marty
Arguments:
Returns:
Dictionary containing the response received from Marty
send_file(filename: str, progress_callback: Callable[[int, int], bool] = None, file_dest: str = 'fs') -> bool
Upload a file from the computer to Marty. 2️⃣
Returns True if uploading succeeds. Operating-system or connection failures can raise exceptions.
def upload_progress(bytes_sent, total_bytes):
print(bytes_sent, "of", total_bytes)
return True
my_marty.send_file("example.mp3", progress_callback=upload_progress)
get_file_list() -> List[str]
Request the files stored on Marty. 2️⃣ Returns the list supplied by firmware, or an empty list if the file-list request fails.
Although the 3.8.0 annotation is List[str], entries can be file-information dictionaries rather than plain filename strings. Inspect the returned entries instead of assuming a string-only list.
delete_file(filename: str) -> bool
Delete a stored file from Marty. 2️⃣
Returns True if the delete request succeeds. Deletion is destructive; only delete files you intentionally want to remove.
register_logging_callback(loggingCallback: Callable[[str], None]) -> None
Register a function to receive each RIC log message. 2️⃣ Primarily useful for debugging.
Returns None. Keep callbacks short; do not run long movement/wait operations inside communication callbacks.
register_publish_callback(messageCallback: Callable[[int], None]) -> None
Register a function called after each published telemetry message has been decoded. 2️⃣
Compare the topic with Marty.PUBLISH_TOPIC_ACCELEROMETER, Marty.PUBLISH_TOPIC_SERVOS, Marty.PUBLISH_TOPIC_POWER, Marty.PUBLISH_TOPIC_ADDONS or Marty.PUBLISH_TOPIC_ROBOT_STATUS, then read the updated data with the normal getter methods. Returns None. Keep callbacks short.
register_report_callback(messageCallback: Callable[[str], None]) -> None
Register a function to receive RIC report messages, including alerts. 2️⃣
Reports may include msgType (such as 'warn'), msgBody (such as 'freeFallDet' or 'overCurrentDet') and IDNo for the hardware element. Returns None. Parse with json.loads when needed, and keep callbacks short.
get_interface_stats() -> Dict
Read communication statistics for debugging. 2️⃣
The dictionary may include roundTripAvgMS, msgRxRatePS, msgTxRatePS, unmatched, matched, unnumbered, timedOut, uploadBPS, rxCount and txCount. Published telemetry rates can appear as servosPS, imuPS, robotPS, powerPS or addonsPS. Available keys depend on the interface.
get_test_output() -> str
Read output captured by MartyPy's test interface. For automated library testing with method='test', not for reading a normal robot connection's program output.
These are legacy interfaces. Use get_ready rather than hello for new programs.
enable_motors(enable: bool = True, clear_queue: bool = True) -> bool
Toggle power to motors 1️⃣
Arguments:
On V1, disabling motors returns False even when the disable command succeeds; do not treat that return value alone as proof of a communication failure.
enable_safeties(enable: bool = True) -> bool
Tell the board to turn on 'normal' safeties 1️⃣
fall_protection(enable: bool = True) -> bool
Toggle fall protections 1️⃣
Arguments:
motor_protection(enable: bool = True) -> bool
Toggle motor current protections 1️⃣
Arguments:
battery_protection(enable: bool = True) -> bool
Toggle low battery protections 1️⃣
Arguments:
buzz_prevention(enable: bool = True) -> bool
Toggle motor buzz prevention 1️⃣
Arguments:
lifelike_behaviour(enable: bool = True) -> bool
Tell the robot whether it can or can't move now and then in a lifelike way when idle. 1️⃣
Arguments:
ros_command(*byte_array: int) -> bool
Low level proxied access to the ROS Serial API between the modem and main controller 1️⃣
keyframe(time: float, num_of_msgs: int, msgs) -> List[bytes]
Takes in information about movements and generates keyframes returns a list of bytes 1️⃣
Arguments:
get_chatter() -> bytes
Return chatter topic data (variable length) 1️⃣
get_firmware_version() -> bool
Ask the board to print the firmware version over chatter 1️⃣
ros_serial_formatter(topicID: int, send: bool = False, *message: int) -> List[int]
Formats message into ROS serial format and returns formatted message as a list 1️⃣
Calls ros_command with the processed message if send is True. More information about the ROS serial format can be found here: http://wiki.ros.org/rosserial/Overview/Protocol
pinmode_gpio(gpio: int, mode: str) -> bool
Configure a GPIO pin 1️⃣
Arguments:
write_gpio(gpio: int, value: int) -> bool
Write a value to a GPIO port 1️⃣
digitalread_gpio(gpio: int) -> bool
Read from GPIO 1️⃣
Arguments:
GPIO pin number, >= 0 (non-negative)
Returns:
Returns High/Low state of a GPIO pin
set_parameter(*byte_array: int) -> bool
Set board parameters 1️⃣
Arguments:
i2c_write(*byte_array: int) -> bool
Write a bytestream to the i2c port. 1️⃣
The first byte should be the address, following from that the datagram folows standard i2c spec
i2c_write_to_ric(address: int, byte_array: bytes) -> bool
Write a formatted bytestream to the i2c port. 1️⃣
The bytestream is formatted in the ROS serial format.
address: the other device's address
i2c_write_to_rick(address: int, byte_array: bytes) -> bool
Write a formatted bytestream to the i2c port. 1️⃣
The bytestream is formatted in the ROS serial format. address: the other device's address
get_battery_voltage() -> float
Get the voltage of the battery 1️⃣
Returns:
The battery voltage reading as a float in Volts
hello(blocking: Optional[bool] = None) -> bool
Zero joints and wiggle eyebrows. 1️⃣ 2️⃣ On V2 this calls the get-ready trajectory; use get_ready for new programs. The optional blocking override works like other movement methods that expose blocking.
discover() -> List[str]
Try and find us some Martys! 1️⃣
__del__() -> None
Object cleanup hook, which calls close. Normally invoked by Python; do not rely on its timing to stop a robot or release a connection. Use close explicitly.