examples/raspberry-pi/my-dalek/README.md
This is an example of using the Moonshine Voice library to build a voice interface that could control a robot from your Raspberry Pi (Dalek not included).
To run it, first cd into this directory and install the Moonshine Voice pip package:
pip install moonshine-voice
If you see a warning about system packages, you can either override that with an uneccessarily scary-sounding flag:
pip install --break-system-packages moonshine-voice
Or use a virtual environment:
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv
source .venv/bin/activate
uv pip install moonshine-voice
If you're using uv, you'll need to run source .venv/bin/activate every time you log back in before you can run the script.
Then make sure you have a USB microphone plugged into your Pi so the script can hear you.
After that's working, run the script:
python my-dalek.py
You should see output like this:
============================================================
š¤ Listening for voice commands...
Try saying phrases with the same meaning as these actions:
- 'move forward'
- 'move backward'
- 'turn left'
- 'turn right'
- 'kill all humans'
- 'exterminate'
We're doing fuzzy matching of natural language, so phrases like 'Go forward' or 'Move ahead' or 'Advance' will trigger the 'move forward' action, for example.
============================================================
Press Ctrl+C to stop.
As the instructions suggest, try saying some phrases you might use to control a robot's movement or actions, like "Go ahead" or "Murder everyone".
If you look at the code, you will see that we have a set of functions that we match to the phrases that should trigger them:
def on_move_forward(d):
print("Moving forward")
def on_move_backward(d):
print("Moving backward")
def on_turn_left(d):
print("Turning left")
def on_turn_right(d):
print("Turning right")
def on_exterminate(d):
print("EXTERMINATE!")
commands = {
"move forward": on_move_forward,
"move backward": on_move_backward,
"turn left": on_turn_left,
"turn right": on_turn_right,
"kill all humans": on_exterminate,
"exterminate": on_exterminate,
}
dalek = DialogFlow()
for phrase, handler in commands.items():
dalek.always(phrase, handler)
dalek.load()
dalek.start_listening()
DialogFlow is the entry point for voice interfaces. Here we only register
"globals" ā single-shot commands that are live at all times ā but the same
runner also handles multi-turn conversations through listen_for, where it can
ask a question, wait for the answer, and confirm it. Either way, load()
downloads and opens the models it needs and start_listening() opens the
microphone, so there's nothing else to wire up.
In a real project each function would have code that controls the robot's wheels, or activates its sink-plunger death-ray, but since I've had trouble understanding Davros's documentation, I've left acquiring the hardware and implementing those as an exercise for the reader.
You can also change the phrases to whatever you need for your application, and the same kind of semantic matching (recognizing sentences that have similar meanings to the target) will work for them too. We've seen people use this for everything from controlling industrial machinery to answering frequently-asked questions, so let us know how you get on!