Python Snippets

Use Azure speech backend

robot.say() uses acapela by default. To use azure instead:

import asyncio
import navel

async def main():
    async with navel.Robot() as robot:
        robot.set_speech_backend(
            "azure",
            speech_key="...",
            speech_region="...",
            locale="en-US",
            voice_name="en-US-AvaMultilingualNeural",
        )
        await robot.say("Hello from Azure.")

if __name__ == "__main__":
    asyncio.run(main())

Set speaker volume

import navel

with navel.Robot() as robot:
    print(f"Previous volume: {robot.volume}%")
    robot.volume += 3
    print(f"New volume: {robot.volume}%")

Stream audio to Google ASR

In your virtual environment, pip install pyaudio.

Follow examples on Github.

You can configure what microphone to use by adding an input_device_index in self._audio_interface.open().

To list the available devices with indices, use the following code.

import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
    print(p.get_device_info_by_index(i))

Disable automatic facial expressions

Facial expressions are in auto-mode by default, which weakens your manual control. You can disable it until restart with the following code.

import navel

with navel.Robot() as robot:
    robot.config_set("cns_fer_cont_t1", 0, navel.DataType.U32)
    robot.config_set("cns_fer_cont_t2", 0, navel.DataType.U32)
    robot.config_set("cns_fer_peak_t1", 0, navel.DataType.U32)
    robot.config_set("cns_fer_peak_t2", 0, navel.DataType.U32)
    robot.config_set("cns_fer_overlay_inc", 0, navel.DataType.F32)
    robot.config_set("cns_fer_overlay_max", 0, navel.DataType.F32)
    robot.config_set("cns_fer_overlay_peak_min", 0, navel.DataType.F32)
    robot.config_set("cns_fer_peak_max", 0, navel.DataType.F32)

Read camera frame

Use HeadCamera or ChestCamera to fetch a single RGB frame on demand. Frames are returned as numpy.ndarray in HWC format (height x width x 3) with uint8 values. The frame timestamp is in microseconds.

import os
import time
from datetime import datetime

from navel import ChestCamera, HeadCamera


SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
OUT_DIR = os.path.join(SCRIPT_DIR, "camera_frames")


def _write_ppm(path, data, width, height):
    header = f"P6\n{width} {height}\n255\n".encode("ascii")
    with open(path, "wb") as f:
        f.write(header)
        f.write(data.tobytes())


def _write_frame(prefix, out_dir, frame):
    ts = datetime.fromtimestamp(frame.timestamp_us / 1_000_000)
    stamp = ts.strftime("%Y%m%d_%H%M%S_%f")
    path = os.path.join(out_dir, f"{prefix}_{stamp}.ppm")
    _write_ppm(path, frame.data, frame.width, frame.height)
    print(f"wrote {path}")


if __name__ == "__main__":
    os.makedirs(OUT_DIR, exist_ok=True)

    try:
        with HeadCamera() as head_cam, ChestCamera() as chest_cam:
            while True:
                head_frame = head_cam.get_frame(timeout_ms=500)
                _write_frame("head", OUT_DIR, head_frame)

                chest_frame = chest_cam.get_frame(timeout_ms=500)
                _write_frame("chest", OUT_DIR, chest_frame)

                time.sleep(1.0)
    except KeyboardInterrupt:
        pass

Driving

With this example, the robot drives forward and backward in a loop. Make sure the robot has clear space and is safe to move before running it.

#!/usr/bin/env python3

import asyncio
import navel

async def drive(robot: navel.Robot, cycles: int = 2):
    for i in range(cycles):
        print(f"{i} forwards")
        await robot.move_base(2, speed=0.5)
        print(f"{i} backwards")
        await robot.move_base(-2, speed=0.5)

async def main():
    async with navel.Robot() as robot:
        await drive(robot, cycles=2)

if __name__ == "__main__":
    asyncio.run(main())