A3_text_to_speach/.env.example
2026-09-03 00:10:18 +04:00

277 lines
11 KiB
Plaintext

# =============================================================================
# AGIBOT A3 - Voice Control | configuration
# =============================================================================
# Copy this file to `.env` and edit that copy. Nothing in the source code needs
# to change to switch between the simulator and the real robot.
#
# Restart the server after editing, or press "Reload config" in the dashboard.
# =============================================================================
# -----------------------------------------------------------------------------
# 1. WEB SERVER (this PC)
# -----------------------------------------------------------------------------
# 127.0.0.1 = only this PC can open the dashboard (recommended).
# 0.0.0.0 = other devices on your LAN can open it too (tablet, phone).
HOST=127.0.0.1
PORT=8000
LOG_LEVEL=info
# Only needed if you serve the frontend from a different origin. Usually empty.
CORS_ORIGINS=
# -----------------------------------------------------------------------------
# 2. ROBOT MODE <<< THIS IS THE SWITCH >>>
# -----------------------------------------------------------------------------
# mock = simulated robot, no hardware required (default; use this today)
# real = talk to a physical AGIBOT A3 over the network
ROBOT_MODE=mock
ROBOT_NAME=AGIBOT A3
ROBOT_MODEL=AgiBot A3
# -----------------------------------------------------------------------------
# 3. ROBOT ADDRESS <<< PUT THE ROBOT IP HERE WHEN YOU HAVE IT >>>
# -----------------------------------------------------------------------------
# Leave ROBOT_IP empty while ROBOT_MODE=mock.
# When the robot is powered on and on the same LAN:
# ROBOT_MODE=real
# ROBOT_IP=192.168.1.50 <- the robot's actual IP on YOUR network
# ROBOT_PORT=59301 <- AgiBot's documented A3 TTS RPC port (HDU)
#
# NOTE: AgiBot's own examples use 10.42.10.10 - that is the robot's INTERNAL
# address for its head unit (HDU) and is not reachable from your PC. Use the
# HDU's address on your WiFi/LAN. Find it with: python scripts/discover_robot.py
ROBOT_IP=
ROBOT_PORT=59301
ROBOT_USE_TLS=false
# Timing (seconds). Keep connect timeout short so the UI never feels stuck.
ROBOT_CONNECT_TIMEOUT=3.0
ROBOT_REQUEST_TIMEOUT=8.0
ROBOT_HEALTH_INTERVAL=5.0
ROBOT_RECONNECT_MIN_DELAY=1.0
ROBOT_RECONNECT_MAX_DELAY=15.0
# -----------------------------------------------------------------------------
# 4. HOW TO TALK TO THE A3
# -----------------------------------------------------------------------------
# Only used when ROBOT_MODE=real.
#
# aimdk - AgiBot's documented A3 speech RPC <<< USE THIS, it is the default >>>
# http - a generic HTTP/REST endpoint you specify yourself
# ws - a WebSocket endpoint you specify yourself
# ros2 - a ROS 2 topic or service (requires ROS 2 on this PC)
# ssh - run a command on the robot over SSH (last-resort fallback)
#
# The `aimdk` transport implements the interface AgiBot documents for the A3:
# POST http://<robot>:59301/rpc/aimdk.protocol.TTSService/PlayTTS
# Content-Type: application/json
# {"text": "...", "priority_level": "INTERACTION_L6", "domain": "...",
# "trace_id": "...", "is_interrupted": true}
# Docs: https://open.agibot.com/docs/en/aimdk/a3/v3_2/dev_guide/07-02-audio_play
#
# The defaults below come from that documentation, but they are still settings
# rather than hard-coded values: AgiBot does not guarantee ports or names across
# firmware, and there is no endpoint-discovery API. If your unit differs, change
# it here - never in the source. See docs/AGIBOT_A3_INTEGRATION.md.
A3_TRANSPORT=aimdk
# --- 4a. AimDK transport (recommended) ---------------------------------------
# Uses ROBOT_IP and ROBOT_PORT above.
A3_AIMDK_SERVICE=aimdk.protocol.TTSService
A3_AIMDK_PLAY_METHOD=PlayTTS
A3_AIMDK_STOP_METHOD=StopTTSTraceId
A3_AIMDK_STATUS_METHOD=GetAudioStatus
# Playback priority. Only INTERACTION_L6 appears in AgiBot's A3 examples.
A3_AIMDK_PRIORITY=INTERACTION_L6
# Free-form caller tag sent with each request, so robot-side logs show who spoke.
A3_AIMDK_DOMAIN=voice_control
# true = a new utterance interrupts whatever is currently playing.
A3_AIMDK_INTERRUPT=true
# Hard request limit documented by AgiBot: 1024 BYTES of UTF-8 (not characters).
# Longer text is split automatically on sentence boundaries and sent in order.
A3_AIMDK_MAX_BYTES=1024
# --- 4b. Generic HTTP / REST transport ---------------------------------------
# Only needed if your unit does NOT use the AimDK interface above.
# Path is relative to http://ROBOT_IP:ROBOT_PORT
# Example shape only - replace with the documented endpoint:
# A3_HTTP_SPEAK_PATH=/api/v1/tts/speak
A3_HTTP_SPEAK_PATH=
A3_HTTP_SPEAK_METHOD=POST
# JSON body template. {text} is replaced with the operator's text.
# Placeholders: {text} {id} {voice} {language} {volume} {speed}
# A key whose value resolves to nothing is dropped from the request.
A3_HTTP_SPEAK_PAYLOAD={"text": "{text}"}
# Optional: endpoint that interrupts speech.
A3_HTTP_STOP_PATH=
A3_HTTP_STOP_METHOD=POST
A3_HTTP_STOP_PAYLOAD={}
# Optional: cheap endpoint polled for the connection indicator.
# If left empty the app falls back to a TCP connect test on ROBOT_PORT.
A3_HTTP_STATUS_PATH=
A3_HTTP_STATUS_METHOD=GET
# Optional: extra headers and auth.
A3_HTTP_HEADERS={}
A3_HTTP_AUTH_TOKEN=
# Optional: dotted path to a success flag in the JSON response, e.g. "code" or
# "result.success". Leave empty to trust the HTTP status code alone.
A3_HTTP_SUCCESS_FIELD=
# --- 4c. WebSocket transport --------------------------------------------------
A3_WS_PATH=
A3_WS_SPEAK_PAYLOAD={"text": "{text}"}
A3_WS_STOP_PAYLOAD={}
A3_WS_PING_INTERVAL=20
# Optional: how the robot announces "finished speaking". With these set, the
# dashboard shows real completion instead of an estimate.
# A3_WS_DONE_FIELD=event
# A3_WS_DONE_VALUE=speech_end
A3_WS_DONE_FIELD=
A3_WS_DONE_VALUE=
# --- 4d. ROS 2 transport ------------------------------------------------------
# Requires ROS 2 installed on this PC and the same ROS_DOMAIN_ID as the robot.
A3_ROS_DOMAIN_ID=0
A3_ROS_SPEAK_TOPIC=
A3_ROS_SPEAK_MSG_TYPE=std_msgs/msg/String
A3_ROS_SPEAK_MSG_FIELD=data
A3_ROS_STOP_TOPIC=
A3_ROS_USE_SERVICE=false
A3_ROS_SERVICE_NAME=
A3_ROS_SERVICE_TYPE=
# --- 4e. SSH transport (last resort) --------------------------------------------
# Runs a command on the robot's own Linux computer. {text} is shell-quoted.
# A3_SSH_SPEAK_COMMAND=<the command that makes your robot speak> {text}
A3_SSH_USER=root
A3_SSH_PORT=22
A3_SSH_KEY_PATH=
A3_SSH_PASSWORD=
A3_SSH_SPEAK_COMMAND=
A3_SSH_STOP_COMMAND=
A3_SSH_PROBE_COMMAND=true
# --- 4f. Optional TTS parameters (sent only when set) -------------------------
A3_VOICE=
A3_LANGUAGE=
A3_VOLUME=
A3_SPEED=
# -----------------------------------------------------------------------------
# 5. SPEECH BEHAVIOUR
# -----------------------------------------------------------------------------
SPEECH_MAX_LENGTH=1000
SPEECH_MIN_LENGTH=1
# true = pressing Speak while talking interrupts and says the new text
# false = pressing Speak while talking is rejected with "already speaking"
SPEECH_ALLOW_INTERRUPT=true
SPEECH_HISTORY_LIMIT=100
# -----------------------------------------------------------------------------
# 6. MOCK ROBOT (ROBOT_MODE=mock only)
# -----------------------------------------------------------------------------
MOCK_CONNECT_DELAY_MS=350
MOCK_NETWORK_LATENCY_MS=45
MOCK_PROCESSING_MS=180
MOCK_WORDS_PER_MINUTE=150
# Set to 0.2 to make 1 in 5 utterances fail, for testing error handling.
MOCK_FAILURE_RATE=0.0
# Set to true to make the simulated link drop occasionally, for testing reconnect.
MOCK_FLAKY_CONNECTION=false
# --- PC speaker playback (simulator only) ------------------------------------
# true = the simulator actually SPEAKS the text through this laptop's speakers,
# so you can rehearse a demo before the robot is on the network.
# When this is on, the real audio drives the UI: "Completed" appears exactly when
# the sound stops, and Stop cuts the voice mid-word.
#
# Windows uses the built-in SAPI voices - nothing to install.
# macOS uses `say`. Linux needs: sudo apt install espeak-ng
MOCK_LOCAL_AUDIO=true
# Which PC voice to use (matched against the voice name, case-insensitive).
# python scripts/voices.py list what is installed
# python scripts/voices.py --demo hear each one
#
# NOTE: this is the SIMULATOR's voice, not the robot's - the real A3 synthesises
# speech on-board. The robot's configured voice is "Yunxiao": a MALE TEENAGER,
# multi-language. Windows ships no teenage voice, so the closest approximation is
# its lighter adult male voice (Mark) pitched up a little. It is a stand-in, not
# a match. Run `python scripts/voices.py --demo` to hear the alternatives.
MOCK_VOICE=Mark
# Speaking rate, -10 (slowest) to 10 (fastest). Try -1 or -2 for a noisy room.
MOCK_SPEECH_RATE=0
# Volume, 0-100.
MOCK_SPEECH_VOLUME=100
# Pitch, -10 (deepest) to 10 (highest). Left at 0: raising it makes the voice
# sound affected rather than natural, which is the opposite of what a service
# robot should sound like.
MOCK_SPEECH_PITCH=0
# -----------------------------------------------------------------------------
# 7. GEMINI CLOUD VOICE (simulator only - nothing here touches the real robot)
# -----------------------------------------------------------------------------
# The built-in Windows voice is instant but robotic. Gemini gives the simulator a
# natural neural voice, at the cost of a network round trip.
#
# system = built-in OS voice - instant, robotic
# gemini = Gemini neural voice - natural, ~4s to synthesise new text
MOCK_VOICE_ENGINE=system
# Get a key at https://aistudio.google.com/apikey
GEMINI_API_KEY=
GEMINI_TTS_MODEL=gemini-3.1-flash-tts-preview
# Prebuilt voice. Iapetus ("Clear") is the default: professional and straight,
# which is how a tour-guide robot actually speaks. Charon ("Informative") is the
# same register but deeper and more adult - swap it in if you prefer that.
# Puck / Fenrir read younger but bouncier. Hear them all:
# python scripts/voices.py
GEMINI_VOICE=Iapetus
# Optional acting direction. LEAVE THIS EMPTY. Anything here makes the model
# *perform* the line instead of simply saying it, which sounds theatrical and
# fake for a service robot. Only set it for a deliberate stage character.
GEMINI_TTS_STYLE=
# 0 = never split. Every line is spoken as ONE clip, in one continuous take.
# Set a character count (e.g. 280) only if you want very long paragraphs to
# start speaking before the whole thing is synthesised - the pieces are then
# synthesised separately, and the join between them can be audible.
GEMINI_CHUNK_CHARS=0
# LATENCY: new text takes ~4s (short) to ~8s (paragraph) to synthesise. Audio is
# cached on disk in .voice-cache/, so a repeated line is INSTANT and stays
# instant across restarts. Before a live demo, warm your lines:
# python scripts/warm_voice.py --file demo_lines.txt
# If Gemini is unreachable the simulator falls back to the built-in voice, so a
# network problem never leaves you with silence.