Merge branch 'develop' into 62-appify-the-demo
Browse files- README.md +10 -0
- src/reachy_mini_conversation_app/moves.py +33 -1
README.md
CHANGED
|
@@ -34,6 +34,7 @@ The app follows a layered architecture connecting the user, AI services, and rob
|
|
| 34 |
## Installation
|
| 35 |
|
| 36 |
> [!IMPORTANT]
|
|
|
|
| 37 |
> Windows support is currently experimental and has not been extensively tested. Use with caution.
|
| 38 |
|
| 39 |
### Using uv
|
|
@@ -159,6 +160,15 @@ By default, the app runs in console mode for direct audio interaction. Use the `
|
|
| 159 |
reachy-mini-conversation-app --no-camera
|
| 160 |
```
|
| 161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
## LLM tools exposed to the assistant
|
| 163 |
|
| 164 |
| Tool | Action | Dependencies |
|
|
|
|
| 34 |
## Installation
|
| 35 |
|
| 36 |
> [!IMPORTANT]
|
| 37 |
+
> Before using this app, you need to install [Reachy Mini's SDK](https://github.com/pollen-robotics/reachy_mini/).<br>
|
| 38 |
> Windows support is currently experimental and has not been extensively tested. Use with caution.
|
| 39 |
|
| 40 |
### Using uv
|
|
|
|
| 160 |
reachy-mini-conversation-app --no-camera
|
| 161 |
```
|
| 162 |
|
| 163 |
+
### Troubleshooting
|
| 164 |
+
|
| 165 |
+
- Timeout error:
|
| 166 |
+
If you get an error like this:
|
| 167 |
+
```bash
|
| 168 |
+
TimeoutError: Timeout while waiting for connection with the server.
|
| 169 |
+
```
|
| 170 |
+
It probably means that the Reachy Mini's daemon isn't running. Install [Reachy Mini's SDK](https://github.com/pollen-robotics/reachy_mini/) and start the daemon.
|
| 171 |
+
|
| 172 |
## LLM tools exposed to the assistant
|
| 173 |
|
| 174 |
| Tool | Action | Dependencies |
|
src/reachy_mini_conversation_app/moves.py
CHANGED
|
@@ -723,13 +723,45 @@ class MovementManager:
|
|
| 723 |
logger.debug("Move worker started")
|
| 724 |
|
| 725 |
def stop(self) -> None:
|
| 726 |
-
"""Request the worker thread to stop and wait for it to exit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
self._stop_event.set()
|
| 728 |
if self._thread is not None:
|
| 729 |
self._thread.join()
|
| 730 |
self._thread = None
|
| 731 |
logger.debug("Move worker stopped")
|
| 732 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 733 |
def get_status(self) -> Dict[str, Any]:
|
| 734 |
"""Return a lightweight status snapshot for observability."""
|
| 735 |
with self._status_lock:
|
|
|
|
| 723 |
logger.debug("Move worker started")
|
| 724 |
|
| 725 |
def stop(self) -> None:
|
| 726 |
+
"""Request the worker thread to stop and wait for it to exit.
|
| 727 |
+
|
| 728 |
+
Before stopping, resets the robot to a neutral position.
|
| 729 |
+
"""
|
| 730 |
+
if self._thread is None or not self._thread.is_alive():
|
| 731 |
+
logger.debug("Move worker not running; stop() ignored")
|
| 732 |
+
return
|
| 733 |
+
|
| 734 |
+
logger.info("Stopping movement manager and resetting to neutral position...")
|
| 735 |
+
|
| 736 |
+
# Clear any queued moves and stop current move
|
| 737 |
+
self.clear_move_queue()
|
| 738 |
+
|
| 739 |
+
# Stop the worker thread first so it doesn't interfere
|
| 740 |
self._stop_event.set()
|
| 741 |
if self._thread is not None:
|
| 742 |
self._thread.join()
|
| 743 |
self._thread = None
|
| 744 |
logger.debug("Move worker stopped")
|
| 745 |
|
| 746 |
+
# Reset to neutral position using goto_target (same approach as wake_up)
|
| 747 |
+
try:
|
| 748 |
+
neutral_head_pose = create_head_pose(0, 0, 0, 0, 0, 0, degrees=True)
|
| 749 |
+
neutral_antennas = [0.0, 0.0]
|
| 750 |
+
neutral_body_yaw = 0.0
|
| 751 |
+
|
| 752 |
+
# Use goto_target directly on the robot
|
| 753 |
+
self.current_robot.goto_target(
|
| 754 |
+
head=neutral_head_pose,
|
| 755 |
+
antennas=neutral_antennas,
|
| 756 |
+
duration=2.0,
|
| 757 |
+
body_yaw=neutral_body_yaw,
|
| 758 |
+
)
|
| 759 |
+
|
| 760 |
+
logger.info("Reset to neutral position completed")
|
| 761 |
+
|
| 762 |
+
except Exception as e:
|
| 763 |
+
logger.error(f"Failed to reset to neutral position: {e}")
|
| 764 |
+
|
| 765 |
def get_status(self) -> Dict[str, Any]:
|
| 766 |
"""Return a lightweight status snapshot for observability."""
|
| 767 |
with self._status_lock:
|