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

Drag Race mode #2

Open
kbennett2000 opened this issue Nov 15, 2024 · 0 comments
Open

Drag Race mode #2

kbennett2000 opened this issue Nov 15, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@kbennett2000
Copy link
Owner

Remote control mode:

  • Enter timing session request
  • Check "Drag Race" option
  • Number of laps parameter is hidden, we will use 1
  • configure additional parameters:
  • START DELAY: how long to wait after the session request is picked up to start the timer
  • After start delay, play countdown beeps
  • Start timing session after the last beep
  • Stop timing session after motion is detected

Drag race sessions should be displayed differently:

  • Best Lap, Worst lap should be ignored (there is only one lap)

Component to measure 132 foot track?

  • Configurable track length? Default to 132?

PROTOTYPE:
https://claude.ai/chat/7a0e4310-d9b5-41dd-a21d-4f9d01e3bd7c

This implementation:

  • Uses GPS to mark start line
  • Continuously updates distance as user walks
  • Shows directional arrow to maintain straight line
  • Alerts when 132ft reached
  • Main limitation: GPS accuracy (typically ±15-50ft). Best results in open areas away from buildings.
import React, { useState, useEffect } from 'react';
import { MapPin, Navigation2 } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';

const TrackMeasurer = () => {
  const [startPosition, setStartPosition] = useState(null);
  const [currentPosition, setCurrentPosition] = useState(null);
  const [distance, setDistance] = useState(0);
  const [heading, setHeading] = useState(0);
  const TARGET_DISTANCE = 132; // feet

  // Calculate distance between two points using Haversine formula
  const calculateDistance = (lat1, lon1, lat2, lon2) => {
    const R = 20902231; // Earth radius in feet
    const dLat = (lat2 - lat1) * Math.PI / 180;
    const dLon = (lon2 - lon1) * Math.PI / 180;
    const a = 
      Math.sin(dLat/2) * Math.sin(dLat/2) +
      Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * 
      Math.sin(dLon/2) * Math.sin(dLon/2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return R * c;
  };

  const handleStartPosition = () => {
    if ('geolocation' in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        setStartPosition({
          lat: position.coords.latitude,
          lon: position.coords.longitude
        });
      });
    }
  };

  useEffect(() => {
    let watchId;
    if (startPosition && 'geolocation' in navigator) {
      watchId = navigator.geolocation.watchPosition((position) => {
        const current = {
          lat: position.coords.latitude,
          lon: position.coords.longitude
        };
        setCurrentPosition(current);
        
        const dist = calculateDistance(
          startPosition.lat, 
          startPosition.lon,
          current.lat,
          current.lon
        );
        setDistance(dist);

        // Calculate heading
        const dLon = (current.lon - startPosition.lon) * Math.PI / 180;
        const y = Math.sin(dLon) * Math.cos(current.lat * Math.PI / 180);
        const x = Math.cos(startPosition.lat * Math.PI / 180) * Math.sin(current.lat * Math.PI / 180) -
                Math.sin(startPosition.lat * Math.PI / 180) * Math.cos(current.lat * Math.PI / 180) * Math.cos(dLon);
        const brng = Math.atan2(y, x) * 180 / Math.PI;
        setHeading((brng + 360) % 360);
      });
    }
    return () => {
      if (watchId) navigator.geolocation.clearWatch(watchId);
    };
  }, [startPosition]);

  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>RC Track Measurer</CardTitle>
      </CardHeader>
      <CardContent>
        <div className="flex flex-col items-center gap-4">
          {!startPosition ? (
            <button 
              onClick={handleStartPosition}
              className="flex items-center gap-2 px-4 py-2 bg-blue-500 text-white rounded-lg"
            >
              <MapPin size={20} />
              Mark Start Line
            </button>
          ) : (
            <div className="text-center space-y-4">
              <div className="flex items-center justify-center text-4xl">
                <Navigation2 
                  size={48}
                  style={{ transform: `rotate(${heading}deg)` }}
                  className="text-blue-500"
                />
              </div>
              <div className="space-y-2">
                <p className="text-2xl font-bold">
                  {distance.toFixed(1)} ft
                </p>
                <p className={`text-lg ${Math.abs(distance - TARGET_DISTANCE) < 1 ? 'text-green-500' : ''}`}>
                  {distance < TARGET_DISTANCE 
                    ? `Keep walking: ${(TARGET_DISTANCE - distance).toFixed(1)} ft to go`
                    : `Too far: ${(distance - TARGET_DISTANCE).toFixed(1)} ft past`}
                </p>
              </div>
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
};

export default TrackMeasurer;
@kbennett2000 kbennett2000 added the enhancement New feature or request label Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant