Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a bore-sight to know where the front of the robot is pointing #30

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,28 @@ jobs:
# node-version: 20 # The specific version of Node that should be used to build your site. Defaults to 20. (optional)
# package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)

deploy:
lighthouse:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout your repository using git
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Run Lighthouse CI
run: npm run lighthouse

deploy:
needs: [build, lighthouse]
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v4
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@
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. [Lighthouse Audit](#lighthouse-audit)
10. [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.

Expand Down Expand Up @@ -82,6 +86,31 @@ 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.

## 🌟 Lighthouse Audit

We have integrated Lighthouse CI into our continuous integration process to ensure the highest quality of our web application. Lighthouse CI runs audits for performance, accessibility, best practices, SEO, and more.

### Running Lighthouse CI Locally

To run Lighthouse CI locally, use the following command:

```sh
npm run lighthouse
```

This will execute the Lighthouse CI audit and provide a detailed report of the results.

## 📝 Citation

If you'd like to cite this project, please use this BibTex:
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
"astro": "astro",
"lighthouse": "lhci autorun"
},
"dependencies": {
"@astrojs/check": "^0.9.4",
Expand All @@ -21,5 +22,8 @@
"react-dom": "^18.3.1",
"tailwindcss": "^3.4.14",
"typescript": "^5.6.3"
},
"devDependencies": {
"lighthouse-ci": "^0.9.0"
}
}
54 changes: 48 additions & 6 deletions src/components/MicMasterFlex.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<Microphone[]>([]);
Expand All @@ -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<SVGSVGElement>(null);
const gridSize = 10; // 10x10 meters grid
Expand Down Expand Up @@ -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 = {
Expand All @@ -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);
}
}
};

Expand Down Expand Up @@ -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(
<line
key="bore-sight"
x1={center.x}
y1={center.y}
x2={arrowEnd.x}
y2={arrowEnd.y}
stroke="#ff0000"
strokeWidth={2}
markerEnd="url(#arrowhead)"
/>
);

return lines;
};

Expand All @@ -197,6 +225,8 @@ const MicMasterFlex = () => {
return 'not-allowed';
case 'edit':
return 'pointer';
case 'adjust-bore-sight':
return 'crosshair';
default:
return 'default';
}
Expand Down Expand Up @@ -234,6 +264,13 @@ const MicMasterFlex = () => {
>
<Trash2 size={20} />
</button>
<button
onClick={() => setMode('adjust-bore-sight')}
className={`p-2 bg-white rounded-full shadow hover:bg-gray-100 ${mode === 'adjust-bore-sight' ? 'ring-2 ring-blue-500' : ''}`}
title="Adjust Bore-Sight"
>
<ArrowUp size={20} />
</button>
<button
onClick={() => setZoom(z => Math.min(z * 1.2, 200))}
className="p-2 bg-white rounded-full shadow hover:bg-gray-100"
Expand All @@ -259,6 +296,11 @@ const MicMasterFlex = () => {
onMouseUp={handleMouseUp}
onMouseLeave={() => setIsDragging(false)}
>
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="0" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#ff0000" />
</marker>
</defs>
<g>
{generateGridLines()}
{microphones.map(mic => {
Expand Down Expand Up @@ -357,4 +399,4 @@ const MicMasterFlex = () => {
);
};

export default MicMasterFlex;
export default MicMasterFlex;