diff --git a/README.md b/README.md index 44c2682..cb44703 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,14 @@ 5. [Running the project locally](#running-the-project-locally) 6. [Building the project locally](#building-the-project-locally) 7. [Project structure](#project-structure) -8. [Citation](#citation) +8. [Bore-Sight Feature](#bore-sight-feature) +9. [Citation](#citation) ## 📸 Demo https://github.com/user-attachments/assets/419bda8b-d6a5-4f54-87b8-acef9d752226 +The demo now includes a bore-sight feature to indicate the front of the robot. This feature helps in visualizing the robot's orientation and front direction. + ## 💡 Project Motivation **MicMasterFlex** was born out of challenges encountered during the [*Robots as Furniture*](https://github.com/robotsasfurniture/passive-sound-localization) project at [Brown University Human-centered Robotics Initiative](https://hcri.brown.edu/), where configuring a microphone array for sound localization required precise positioning of multiple microphones. @@ -82,6 +85,16 @@ There's nothing special about `src/components/`, but that's where we like to put Any static assets, like images, can be placed in the `public/` directory. +## 📝 Bore-Sight Feature + +The bore-sight feature in MicMasterFlex allows users to visualize the front direction of the robot. This is particularly useful for applications where the orientation of the robot is crucial. The bore-sight is represented by an arrow on the grid, indicating the direction the robot is facing. + +### How to Use + +1. **Adjust Bore-Sight Mode**: Select the "Adjust Bore-Sight" mode from the toolbar. +2. **Drag to Adjust**: Click and drag on the grid to adjust the orientation of the bore-sight arrow. +3. **Visual Feedback**: The arrow will update in real-time to show the new orientation. + ## 📝 Citation If you'd like to cite this project, please use this BibTex: diff --git a/src/components/MicMasterFlex.tsx b/src/components/MicMasterFlex.tsx index 32f472a..a567293 100644 --- a/src/components/MicMasterFlex.tsx +++ b/src/components/MicMasterFlex.tsx @@ -1,5 +1,5 @@ import React, { useState, useRef } from 'react'; -import { Copy, ZoomIn, ZoomOut, PlusCircle, Trash2, Hand, Edit2 } from 'lucide-react'; +import { Copy, ZoomIn, ZoomOut, PlusCircle, Trash2, Hand, Edit2, ArrowUp } from 'lucide-react'; type Microphone = { id: string; @@ -12,7 +12,7 @@ type Point = { y: number; } -type Mode = 'pan' | 'add' | 'delete' | 'edit'; +type Mode = 'pan' | 'add' | 'delete' | 'edit' | 'adjust-bore-sight'; const MicMasterFlex = () => { const [microphones, setMicrophones] = useState([]); @@ -26,6 +26,7 @@ const MicMasterFlex = () => { const [showEditDialog, setShowEditDialog] = useState(false); const [editX, setEditX] = useState(''); const [editY, setEditY] = useState(''); + const [orientation, setOrientation] = useState(0); // Pac1c const svgRef = useRef(null); const gridSize = 10; // 10x10 meters grid @@ -59,7 +60,7 @@ const MicMasterFlex = () => { // Handle mouse move const handleMouseMove = (e: React.MouseEvent) => { - if (!svgRef.current || !isDragging || mode !== 'pan') return; + if (!svgRef.current || !isDragging) return; const rect = svgRef.current.getBoundingClientRect(); const point = { @@ -70,8 +71,14 @@ const MicMasterFlex = () => { if (dragStart) { const dx = point.x - dragStart.x; const dy = point.y - dragStart.y; - setPan(prev => ({ x: prev.x + dx, y: prev.y + dy })); - setDragStart(point); + + if (mode === 'pan') { + setPan(prev => ({ x: prev.x + dx, y: prev.y + dy })); + setDragStart(point); + } else if (mode === 'adjust-bore-sight') { + const angle = Math.atan2(dy, dx) * (180 / Math.PI); + setOrientation(angle); + } } }; @@ -171,6 +178,27 @@ const MicMasterFlex = () => { ); } + // Add bore-sight arrow + const center = gridToScreen({ x: 0, y: 0 }); + const arrowLength = 50; // Length of the arrow in pixels + const arrowEnd = { + x: center.x + arrowLength * Math.cos(orientation * (Math.PI / 180)), + y: center.y + arrowLength * Math.sin(orientation * (Math.PI / 180)), + }; + + lines.push( + + ); + return lines; }; @@ -197,6 +225,8 @@ const MicMasterFlex = () => { return 'not-allowed'; case 'edit': return 'pointer'; + case 'adjust-bore-sight': + return 'crosshair'; default: return 'default'; } @@ -234,6 +264,13 @@ const MicMasterFlex = () => { > +