mirror of
https://github.com/soconnor0919/hristudio.git
synced 2025-12-11 22:54:45 -05:00
🤖 Full NAO6 Robot Integration with ROS2 and WebSocket Control ## New Features - **NAO6 Test Interface**: Real-time robot control via web browser at /nao-test - **ROS2 Integration**: Complete naoqi_driver2 + rosbridge setup with launch files - **WebSocket Control**: Direct robot control through HRIStudio web interface - **Plugin System**: NAO6 robot plugins for movement, speech, and sensors - **Database Integration**: Updated seed data with NAO6 robot and plugin definitions ## Key Components Added - **Web Interface**: src/app/(dashboard)/nao-test/page.tsx - Complete robot control dashboard - **Plugin Repository**: public/nao6-plugins/ - Local NAO6 plugin definitions - **Database Updates**: Updated robots table with ROS2 protocol and enhanced capabilities - **Comprehensive Documentation**: Complete setup, troubleshooting, and quick reference guides ## Documentation - **Complete Integration Guide**: docs/nao6-integration-complete-guide.md (630 lines) - **Quick Reference**: docs/nao6-quick-reference.md - Essential commands and troubleshooting - **Updated Setup Guide**: Enhanced docs/nao6-ros2-setup.md with critical notes - **Updated Main Docs**: docs/README.md with robot integration section ## Robot Capabilities - ✅ **Speech Control**: Text-to-speech with emotion and language support - ✅ **Movement Control**: Walking, turning, stopping with configurable speeds - ✅ **Head Control**: Precise yaw/pitch positioning with sliders - ✅ **Sensor Monitoring**: Joint states, touch sensors, sonar, cameras, IMU - ✅ **Safety Features**: Emergency stop, movement limits, real-time monitoring - ✅ **Real-time Data**: Live sensor data streaming through WebSocket ## Critical Discovery **Robot Wake-Up Requirement**: NAO robots start in safe mode with loose joints and must be explicitly awakened via SSH before movement commands work. This is now documented with automated solutions. ## Technical Implementation - **ROS2 Humble**: Complete naoqi_driver2 integration with rosbridge WebSocket server - **Topic Mapping**: Correct namespace handling for control vs. sensor topics - **Plugin Architecture**: Extensible NAO6 action definitions with parameter validation - **Database Schema**: Enhanced robots table with comprehensive NAO6 capabilities - **Import Consistency**: Fixed React import aliases to use ~ consistently ## Testing & Verification - ✅ Tested with NAO V6.0 / NAOqi 2.8.7.4 / ROS2 Humble - ✅ Complete end-to-end testing from web interface to robot movement - ✅ Comprehensive troubleshooting procedures documented - ✅ Production-ready launch scripts and deployment guides ## Production Ready This integration is fully tested and production-ready for Human-Robot Interaction research with complete documentation, safety guidelines, and troubleshooting procedures.
339 lines
9.8 KiB
JSON
339 lines
9.8 KiB
JSON
{
|
|
"name": "NAO6 Speech & Audio",
|
|
"version": "1.0.0",
|
|
"description": "Text-to-speech and audio capabilities for NAO6 robot including voice synthesis, volume control, and language settings",
|
|
"platform": "NAO6",
|
|
"category": "speech",
|
|
"manufacturer": {
|
|
"name": "SoftBank Robotics",
|
|
"website": "https://www.softbankrobotics.com"
|
|
},
|
|
"documentation": {
|
|
"mainUrl": "https://docs.hristudio.com/robots/nao6/speech",
|
|
"quickStart": "https://docs.hristudio.com/robots/nao6/speech/quickstart"
|
|
},
|
|
"ros2Config": {
|
|
"namespace": "/naoqi_driver",
|
|
"topics": {
|
|
"speech": {
|
|
"type": "std_msgs/String",
|
|
"description": "Text-to-speech commands"
|
|
},
|
|
"set_language": {
|
|
"type": "std_msgs/String",
|
|
"description": "Set speech language"
|
|
},
|
|
"audio_volume": {
|
|
"type": "std_msgs/Float32",
|
|
"description": "Control audio volume level"
|
|
}
|
|
}
|
|
},
|
|
"actions": [
|
|
{
|
|
"id": "say_text",
|
|
"name": "Say Text",
|
|
"description": "Make the robot speak the specified text using text-to-speech",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "text",
|
|
"type": "text",
|
|
"description": "Text for the robot to speak",
|
|
"required": true,
|
|
"maxLength": 500,
|
|
"placeholder": "Enter text for NAO to say..."
|
|
},
|
|
{
|
|
"name": "wait_for_completion",
|
|
"type": "boolean",
|
|
"description": "Wait for speech to finish before continuing",
|
|
"required": false,
|
|
"default": true
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/speech",
|
|
"messageType": "std_msgs/String",
|
|
"messageTemplate": {
|
|
"data": "{{text}}"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "say_with_emotion",
|
|
"name": "Say Text with Emotion",
|
|
"description": "Speak text with emotional expression using SSML-like markup",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "text",
|
|
"type": "text",
|
|
"description": "Text for the robot to speak",
|
|
"required": true,
|
|
"maxLength": 500,
|
|
"placeholder": "Enter text for NAO to say..."
|
|
},
|
|
{
|
|
"name": "emotion",
|
|
"type": "select",
|
|
"description": "Emotional tone for speech",
|
|
"required": false,
|
|
"options": [
|
|
{ "value": "neutral", "label": "Neutral" },
|
|
{ "value": "happy", "label": "Happy" },
|
|
{ "value": "sad", "label": "Sad" },
|
|
{ "value": "excited", "label": "Excited" },
|
|
{ "value": "calm", "label": "Calm" }
|
|
],
|
|
"default": "neutral"
|
|
},
|
|
{
|
|
"name": "speed",
|
|
"type": "number",
|
|
"description": "Speech speed multiplier",
|
|
"required": false,
|
|
"min": 0.5,
|
|
"max": 2.0,
|
|
"default": 1.0,
|
|
"step": 0.1
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/speech",
|
|
"messageType": "std_msgs/String",
|
|
"messageTemplate": {
|
|
"data": "\\rspd={{speed}}\\\\rst={{emotion}}\\{{text}}"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "set_volume",
|
|
"name": "Set Volume",
|
|
"description": "Adjust the robot's audio volume level",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "volume",
|
|
"type": "number",
|
|
"description": "Volume level (0.0 = silent, 1.0 = maximum)",
|
|
"required": true,
|
|
"min": 0.0,
|
|
"max": 1.0,
|
|
"default": 0.5,
|
|
"step": 0.1
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/audio_volume",
|
|
"messageType": "std_msgs/Float32",
|
|
"messageTemplate": {
|
|
"data": "{{volume}}"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "set_language",
|
|
"name": "Set Language",
|
|
"description": "Change the robot's speech language",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "language",
|
|
"type": "select",
|
|
"description": "Speech language",
|
|
"required": true,
|
|
"options": [
|
|
{ "value": "en-US", "label": "English (US)" },
|
|
{ "value": "en-GB", "label": "English (UK)" },
|
|
{ "value": "fr-FR", "label": "French" },
|
|
{ "value": "de-DE", "label": "German" },
|
|
{ "value": "es-ES", "label": "Spanish" },
|
|
{ "value": "it-IT", "label": "Italian" },
|
|
{ "value": "ja-JP", "label": "Japanese" },
|
|
{ "value": "ko-KR", "label": "Korean" },
|
|
{ "value": "zh-CN", "label": "Chinese (Simplified)" }
|
|
],
|
|
"default": "en-US"
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/set_language",
|
|
"messageType": "std_msgs/String",
|
|
"messageTemplate": {
|
|
"data": "{{language}}"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "say_random_phrase",
|
|
"name": "Say Random Phrase",
|
|
"description": "Make the robot say a random phrase from predefined categories",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "category",
|
|
"type": "select",
|
|
"description": "Category of phrases",
|
|
"required": true,
|
|
"options": [
|
|
{ "value": "greeting", "label": "Greetings" },
|
|
{ "value": "encouragement", "label": "Encouragement" },
|
|
{ "value": "question", "label": "Questions" },
|
|
{ "value": "farewell", "label": "Farewells" },
|
|
{ "value": "instruction", "label": "Instructions" }
|
|
],
|
|
"default": "greeting"
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/speech",
|
|
"messageType": "std_msgs/String",
|
|
"messageTemplate": {
|
|
"data": "{{getRandomPhrase(category)}}"
|
|
}
|
|
},
|
|
"phrases": {
|
|
"greeting": [
|
|
"Hello! Nice to meet you!",
|
|
"Hi there! How are you today?",
|
|
"Welcome! I'm excited to work with you.",
|
|
"Good day! Ready to get started?",
|
|
"Greetings! What shall we do today?"
|
|
],
|
|
"encouragement": [
|
|
"Great job! Keep it up!",
|
|
"You're doing wonderfully!",
|
|
"Excellent work! I'm impressed.",
|
|
"That's fantastic! Well done!",
|
|
"Perfect! You've got this!"
|
|
],
|
|
"question": [
|
|
"How can I help you today?",
|
|
"What would you like to do next?",
|
|
"Is there anything you'd like to know?",
|
|
"Shall we try something different?",
|
|
"What are you thinking about?"
|
|
],
|
|
"farewell": [
|
|
"Goodbye! It was great working with you!",
|
|
"See you later! Take care!",
|
|
"Until next time! Have a wonderful day!",
|
|
"Farewell! Thanks for spending time with me!",
|
|
"Bye for now! Look forward to seeing you again!"
|
|
],
|
|
"instruction": [
|
|
"Please follow my movements.",
|
|
"Let's try this step by step.",
|
|
"Watch carefully and then repeat.",
|
|
"Take your time, there's no rush.",
|
|
"Remember to stay focused."
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"id": "spell_word",
|
|
"name": "Spell Word",
|
|
"description": "Have the robot spell out a word letter by letter",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "word",
|
|
"type": "text",
|
|
"description": "Word to spell out",
|
|
"required": true,
|
|
"maxLength": 50,
|
|
"placeholder": "Enter word to spell..."
|
|
},
|
|
{
|
|
"name": "pause_duration",
|
|
"type": "number",
|
|
"description": "Pause between letters in seconds",
|
|
"required": false,
|
|
"min": 0.1,
|
|
"max": 2.0,
|
|
"default": 0.5,
|
|
"step": 0.1
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/speech",
|
|
"messageType": "std_msgs/String",
|
|
"messageTemplate": {
|
|
"data": "{{word.split('').join('\\pau={{pause_duration * 1000}}\\\\pau=0\\')}}"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "count_numbers",
|
|
"name": "Count Numbers",
|
|
"description": "Have the robot count from one number to another",
|
|
"category": "speech",
|
|
"parameters": [
|
|
{
|
|
"name": "start",
|
|
"type": "number",
|
|
"description": "Starting number",
|
|
"required": true,
|
|
"min": 0,
|
|
"max": 100,
|
|
"default": 1,
|
|
"step": 1
|
|
},
|
|
{
|
|
"name": "end",
|
|
"type": "number",
|
|
"description": "Ending number",
|
|
"required": true,
|
|
"min": 0,
|
|
"max": 100,
|
|
"default": 10,
|
|
"step": 1
|
|
},
|
|
{
|
|
"name": "pause_duration",
|
|
"type": "number",
|
|
"description": "Pause between numbers in seconds",
|
|
"required": false,
|
|
"min": 0.1,
|
|
"max": 2.0,
|
|
"default": 0.8,
|
|
"step": 0.1
|
|
}
|
|
],
|
|
"implementation": {
|
|
"topic": "/naoqi_driver/speech",
|
|
"messageType": "std_msgs/String",
|
|
"messageTemplate": {
|
|
"data": "{{Array.from({length: end - start + 1}, (_, i) => start + i).join('\\pau={{pause_duration * 1000}}\\\\pau=0\\')}}"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"features": {
|
|
"languages": [
|
|
"en-US", "en-GB", "fr-FR", "de-DE", "es-ES",
|
|
"it-IT", "ja-JP", "ko-KR", "zh-CN"
|
|
],
|
|
"emotions": [
|
|
"neutral", "happy", "sad", "excited", "calm"
|
|
],
|
|
"voiceEffects": [
|
|
"speed", "pitch", "volume", "emotion"
|
|
],
|
|
"ssmlSupport": true,
|
|
"maxTextLength": 500
|
|
},
|
|
"safety": {
|
|
"maxVolume": 1.0,
|
|
"defaultVolume": 0.5,
|
|
"profanityFilter": true,
|
|
"maxSpeechDuration": 60,
|
|
"emergencyQuiet": {
|
|
"action": "set_volume",
|
|
"parameters": { "volume": 0 },
|
|
"description": "Immediately mute robot audio"
|
|
}
|
|
}
|
|
}
|