{"id":36670953,"url":"https://github.com/cprosche/visibility-testing","last_synced_at":"2026-01-12T10:40:43.718Z","repository":{"id":320909486,"uuid":"1083718487","full_name":"cprosche/visibility-testing","owner":"cprosche","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-26T16:29:04.000Z","size":2345,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-26T18:28:40.033Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cprosche.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-26T15:33:30.000Z","updated_at":"2025-10-26T16:29:07.000Z","dependencies_parsed_at":"2025-10-26T18:28:59.369Z","dependency_job_id":null,"html_url":"https://github.com/cprosche/visibility-testing","commit_stats":null,"previous_names":["cprosche/visibility-testing"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/cprosche/visibility-testing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cprosche%2Fvisibility-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cprosche%2Fvisibility-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cprosche%2Fvisibility-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cprosche%2Fvisibility-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cprosche","download_url":"https://codeload.github.com/cprosche/visibility-testing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cprosche%2Fvisibility-testing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338788,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T10:40:25.642Z","status":"ssl_error","status_checked_at":"2026-01-12T10:39:27.820Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-12T10:40:42.985Z","updated_at":"2026-01-12T10:40:43.709Z","avatar_url":"https://github.com/cprosche.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Satellite Visibility Testing Framework\n\n[![Test Suite](https://github.com/caderosche/visibility-testing/actions/workflows/test.yml/badge.svg)](https://github.com/caderosche/visibility-testing/actions/workflows/test.yml)\n[![Performance Benchmark](https://github.com/caderosche/visibility-testing/actions/workflows/benchmark.yml/badge.svg)](https://github.com/caderosche/visibility-testing/actions/workflows/benchmark.yml)\n[![Docker Build](https://github.com/caderosche/visibility-testing/actions/workflows/docker-build.yml/badge.svg)](https://github.com/caderosche/visibility-testing/actions/workflows/docker-build.yml)\n[![Pages](https://github.com/caderosche/visibility-testing/actions/workflows/pages.yml/badge.svg)](https://github.com/caderosche/visibility-testing/actions/workflows/pages.yml)\n\n**[📊 View Live Dashboard](https://caderosche.github.io/visibility-testing/)** | [Documentation](docs/README.md)\n\nA comprehensive, multi-language testing framework for validating satellite visibility calculations. Compare implementations across different programming languages and libraries to ensure accuracy and consistency.\n\n## What is Satellite Visibility Window Calculation?\n\nA **visibility window** is a time period when a satellite is visible from a specific location on Earth. This occurs when the satellite rises above the horizon (at a minimum elevation angle) and remains visible until it sets below that angle again.\n\n### Key Concepts\n\n- **Elevation Angle**: The vertical angle between the horizon and the satellite. 0° means the satellite is on the horizon, 90° means directly overhead (zenith).\n- **Azimuth**: The horizontal direction (compass bearing) where the satellite appears. 0° is North, 90° is East, 180° is South, 270° is West.\n- **Range**: The direct line-of-sight distance from the observer to the satellite (measured in kilometers).\n- **Visibility Window**: A continuous time period when elevation is above a minimum threshold (typically 10°).\n\n### Why This Matters\n\nAccurate visibility predictions are critical for:\n- **Ground station operations**: Knowing when to communicate with satellites\n- **Satellite photography**: Planning when to capture images of satellites\n- **Amateur radio**: Timing communication windows with satellites\n- **Space situational awareness**: Tracking satellite positions for collision avoidance\n- **Scientific observations**: Scheduling telescope time for satellite observations\n\nThis framework validates that different SGP4 implementations produce consistent and accurate visibility predictions across multiple programming languages.\n\n## Overview\n\nThis project provides:\n- **Shared test cases** in a language-agnostic format\n- **Multiple implementations** in different programming languages\n- **Automated validation** to compare results against reference data\n- **Performance benchmarking** to compare execution speed\n- **CI/CD integration** via GitHub Actions\n- **Interactive dashboard** with visualizations and analytics ([view live](https://caderosche.github.io/visibility-testing/))\n\n## Project Status\n\n**Phase 4 Complete!** ✅ All core implementations finished and validated.\n\n- ✅ **6 implementations** across 5 languages (Python x2, JavaScript, Rust, C#, C++)\n- ✅ **10/10 test cases passing** for all implementations\n- ✅ **Docker-based** test orchestration\n- ✅ **CI/CD workflows** for automated testing\n- 📊 Performance range: 0.26s (Rust) to 22s (Skyfield reference)\n\nSee [PLAN.md](PLAN.md) for detailed development roadmap.\n\n## Architecture\n\n```\nvisibility-testing/\n├── test-data/              # Shared test cases and reference results\n│   ├── schema.json         # Test data format specification\n│   ├── cases/              # Input test cases (JSON)\n│   └── reference-results/  # Expected outputs (JSON)\n│\n├── implementations/        # Multiple libraries per language\n│   ├── python-skyfield/    # Primary reference (Skyfield library)\n│   ├── python-sgp4/        # Pure Python SGP4 implementation\n│   ├── python-pyephem/     # Legacy PyEphem library\n│   ├── javascript-satellite.js/  # Most popular JS library\n│   ├── javascript-sgp4/    # Alternative JS implementation\n│   ├── rust-sgp4/          # Primary Rust crate\n│   ├── rust-satellite/     # Alternative Rust implementation\n│   ├── cpp-vallado/        # Reference C++ implementation\n│   ├── cpp-libsgp4/        # Alternative C++ library\n│   ├── csharp-sgpnet/      # Primary .NET implementation\n│   └── csharp-zeptomoby/   # Alternative .NET library\n│\n├── test-runner/            # Orchestration and validation framework\n│   ├── orchestrator.js     # Executes all implementations\n│   ├── validator.js        # Compares results with tolerances\n│   ├── reporter.js         # Generates test reports\n│   ├── storage/            # Result persistence (SQLite/JSON)\n│   └── visualization/      # Chart generation and graphing\n│\n├── .github/workflows/      # CI/CD automation\n│   ├── test.yml            # Main test workflow\n│   └── benchmark.yml       # Performance tracking\n│\n├── docs/                   # Documentation\n│   ├── implementation-guide.md\n│   ├── test-data-format.md\n│   └── tolerance-spec.md\n│\n├── PLAN.md                 # Development roadmap\n└── README.md               # This file\n```\n\n## Multi-Library Testing Strategy\n\nThis framework tests **multiple libraries per language** to:\n- Identify library-specific bugs and accuracy issues\n- Compare performance across different implementations\n- Provide recommendations for which libraries to use\n- Ensure cross-validation within the same language ecosystem\n\n### Libraries by Language\n\n| Language | Libraries Tested | Status |\n|----------|-----------------|--------|\n| **Python** | Skyfield (primary), sgp4, PyEphem | Skyfield is reference |\n| **JavaScript** | satellite.js, sgp4 npm package | TBD |\n| **Rust** | sgp4 crate, satellite-rs | TBD |\n| **C++** | Vallado SGP4, libsgp4 | TBD |\n| **C#** | SGP.NET, Zeptomoby.OrbitTools | TBD |\n\n### Why Multiple Libraries?\n\nDifferent libraries may:\n- Use different numerical precision or algorithms\n- Have implementation bugs\n- Optimize for speed vs. accuracy\n- Have varying levels of maintenance and correctness\n\nBy testing multiple libraries per language, we can:\n1. **Cross-validate** results within the same language\n2. **Identify outliers** - libraries that deviate from consensus\n3. **Recommend best practices** - which library to use for production\n4. **Track improvements** - monitor library updates over time\n\n## Docker-Based Execution\n\n**All implementations run in Docker containers** for maximum reproducibility and portability.\n\n### Why Docker?\n\n- **Reproducibility**: Identical results across different machines and operating systems\n- **Isolation**: No dependency conflicts between implementations\n- **Portability**: Works anywhere Docker is installed (dev machines, CI/CD, servers)\n- **Consistency**: Same environment in local development and production\n\n### Quick Start with Docker\n\n```bash\n# Build all images\ndocker-compose build\n\n# Run all tests\ndocker-compose up\n\n# Run specific implementation\ndocker run --rm \\\n  -v $(pwd)/test-data:/test-data:ro \\\n  -v $(pwd)/results:/results \\\n  visibility-test/python-skyfield\n\n# View results\ncat results/python-skyfield_001_iss_nyc.json\n```\n\n### Docker Requirements\n\nEvery implementation must include:\n- **Dockerfile** with complete build instructions\n- **Pinned dependencies** (requirements.txt, package.json, Cargo.lock, etc.)\n- **Standard volumes**: `/test-data` (read-only), `/results` (write)\n- **Image naming**: `visibility-test/{language}-{library}:latest`\n\nSee [docs/docker-guide.md](docs/docker-guide.md) for complete Docker documentation.\n\n## Test Data Format\n\nEach test case includes:\n\n```json\n{\n  \"name\": \"ISS Pass Over NYC\",\n  \"description\": \"International Space Station visibility from New York City\",\n  \"satellite\": {\n    \"tle\": [\n      \"ISS (ZARYA)\",\n      \"1 25544U 98067A   24001.50000000  .00016717  00000-0  10270-3 0  9005\",\n      \"2 25544  51.6400 247.4627 0001320  67.4605 292.6523 15.54225995123456\"\n    ]\n  },\n  \"observer\": {\n    \"latitude\": 40.7128,\n    \"longitude\": -74.0060,\n    \"altitude\": 0\n  },\n  \"timeWindow\": {\n    \"start\": \"2024-01-01T00:00:00Z\",\n    \"end\": \"2024-01-02T00:00:00Z\",\n    \"step\": 60\n  },\n  \"minElevation\": 10.0\n}\n```\n\nExpected output format:\n\n```json\n{\n  \"testCase\": \"ISS Pass Over NYC\",\n  \"implementation\": \"python\",\n  \"version\": \"1.0.0\",\n  \"visibilityWindows\": [\n    {\n      \"start\": \"2024-01-01T06:23:15Z\",\n      \"end\": \"2024-01-01T06:30:42Z\",\n      \"maxElevation\": 68.5,\n      \"maxElevationTime\": \"2024-01-01T06:27:01Z\",\n      \"points\": [\n        {\n          \"time\": \"2024-01-01T06:23:15Z\",\n          \"azimuth\": 342.5,\n          \"elevation\": 10.2,\n          \"range\": 1423.7,\n          \"rangeRate\": -5.234\n        }\n      ]\n    }\n  ],\n  \"executionTime\": 0.042\n}\n```\n\n## Implementation Interface\n\nEach language implementation must:\n\n1. **Have a Dockerfile** that builds a working container\n2. **Read** test cases from mounted volume `/test-data/cases/*.json`\n3. **Calculate** satellite visibility using the SGP4 propagator\n4. **Output** results to `/results/{implementation}_{testcase}.json`\n5. **Follow Docker naming**: `visibility-test/{language}-{library}:latest`\n\n### Required Calculations\n- Satellite position from TLE (SGP4/SDP4 propagation)\n- Topocentric coordinates (azimuth, elevation, range)\n- Visibility windows (elevation above threshold)\n- Range rate (doppler shift indication)\n\n### Docker Container Interface\nEach implementation runs via Docker:\n```bash\n# Build image\ndocker build -t visibility-test/{language}-{library} implementations/{language}-{library}/\n\n# Run all test cases\ndocker run --rm \\\n  -v $(pwd)/test-data:/test-data:ro \\\n  -v $(pwd)/results:/results \\\n  visibility-test/{language}-{library}\n\n# Or use docker-compose\ndocker-compose up {language}-{library}\n```\n\n## Validation Tolerances\n\nResults are compared with the following tolerances:\n\n| Parameter | Tolerance | Reason |\n|-----------|-----------|--------|\n| Azimuth | ±0.1° | Atmospheric refraction variability |\n| Elevation | ±0.1° | Propagation model differences |\n| Range | ±1.0 km | TLE accuracy limitations |\n| Time | ±1.0 sec | Discrete time step sampling |\n| Range Rate | ±0.1 km/s | Numerical differentiation error |\n\n## Quick Start\n\n### Prerequisites\n- **Docker** (REQUIRED) - Install from [docker.com](https://www.docker.com/get-started)\n- Docker Compose (usually included with Docker Desktop)\n\n### Running Tests Locally\n\n```bash\n# Run all implementations via Docker Compose\ndocker-compose up\n\n# Run specific implementation\ndocker-compose up python-skyfield\n\n# Rebuild and run\ndocker-compose up --build\n\n# View results\nls -la results/\n```\n\n**Alternative: Run individual containers**\n```bash\n# Build specific image\ndocker build -t visibility-test/python-skyfield implementations/python-skyfield/\n\n# Run tests\ndocker run --rm \\\n  -v $(pwd)/test-data:/test-data:ro \\\n  -v $(pwd)/results:/results \\\n  visibility-test/python-skyfield\n```\n\n### Adding a New Language Implementation\n\n1. Create directory: `implementations/{language}-{library}/`\n2. Create Dockerfile with complete build instructions\n2. Implement the standardized interface (see `docs/implementation-guide.md`)\n3. Add Docker configuration for CI\n4. Register in test orchestrator\n5. Run validation: `npm run test:{language}`\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.\n\n## CI/CD\n\nGitHub Actions automatically:\n- Runs all implementations on every push/PR\n- Validates results against reference data\n- Tracks performance benchmarks\n- Fails on tolerance violations\n- Collects and stores results for trending\n- Publishes charts and visualizations\n\n## Interactive Dashboard\n\n**[📊 View Live Dashboard](https://caderosche.github.io/visibility-testing/)**\n\nAn interactive web dashboard visualizes test results and provides comprehensive analytics:\n\n### Features\n- **Performance Rankings** - Real-time comparison of execution times across all implementations\n- **Accuracy Histograms** - Precision analysis with error distribution charts (azimuth, elevation, range)\n- **Test Case Breakdown** - Per-test performance comparison across languages\n- **Implementation Details** - Detailed stats cards for each language/library combination\n- **Dark Theme UI** - Modern, responsive design optimized for readability\n\n### Technologies\n- Static site hosted on GitHub Pages\n- Chart.js for interactive visualizations\n- Automatically updated on every push to master\n- No backend required - pure HTML/CSS/JavaScript\n\n### Local Preview\n```bash\n# Run tests\ncd test-runner \u0026\u0026 cargo run --release -- run\n\n# Update dashboard data\n./docs/update-dashboard.sh\n\n# View locally\ncd docs \u0026\u0026 python3 -m http.server 8000\n# Open http://localhost:8000\n```\n\nSee [docs/README.md](docs/README.md) for dashboard development details.\n\n## Performance Benchmarks\n\nTarget performance (preliminary):\n\n| Language | Avg Time per Test | Relative Speed |\n|----------|-------------------|----------------|\n| Rust | TBD | 1.0x (baseline) |\n| C++ | TBD | ~1.0x |\n| C# | TBD | ~1.5-2x |\n| Python | TBD | ~3-5x |\n| JavaScript | TBD | ~2-4x |\n\n## Use Cases\n\n- **Library Validation**: Verify correctness of satellite tracking libraries\n- **Cross-Platform Testing**: Ensure consistent results across environments\n- **Performance Comparison**: Benchmark execution speed across languages\n- **Educational Tool**: Learn satellite visibility algorithms\n- **Reference Implementation**: Ground truth for new implementations\n\n## Supported Languages and Libraries (Planned)\n\n### Python (Reference Language)\n- [x] **Skyfield** - Primary reference implementation\n- [ ] **sgp4** - Pure Python SGP4\n- [ ] **PyEphem** - Legacy library\n\n### JavaScript/TypeScript\n- [ ] **satellite.js** - Most popular\n- [ ] **sgp4** (npm) - Alternative\n\n### Rust\n- [ ] **sgp4** crate - Primary\n- [ ] **satellite-rs** - Alternative\n\n### C++\n- [ ] **Vallado SGP4** - Reference implementation\n- [ ] **libsgp4** - Alternative\n\n### C#\n- [ ] **SGP.NET** - Primary\n- [ ] **Zeptomoby.OrbitTools** - Alternative\n\n## Roadmap\n\nSee [PLAN.md](PLAN.md) for the complete development roadmap broken into 7 phases:\n\n1. **Foundation \u0026 Infrastructure** - Test data schema and initial cases\n2. **Reference Implementation** - Python implementation with ground truth\n3. **Test Orchestration** - Automated validation framework\n4. **Additional Languages** - Multiple language implementations\n5. **CI/CD Integration** - GitHub Actions automation\n6. **Expansion** - More test cases and features\n7. **Documentation** - Comprehensive guides and tutorials\n\n## Contributing\n\nContributions welcome! Areas of interest:\n- New language implementations\n- Additional test cases\n- Performance optimizations\n- Documentation improvements\n- Visualization tools\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\n[To be determined]\n\n## Resources\n\n### Satellite Tracking Libraries\n\n**Python**:\n- [Skyfield](https://github.com/skyfielders/python-skyfield) - Primary reference, high accuracy\n- [sgp4](https://github.com/brandon-rhodes/python-sgp4) - Pure Python implementation\n- [PyEphem](https://github.com/brandon-rhodes/pyephem) - Legacy but widely used\n\n**JavaScript/TypeScript**:\n- [satellite.js](https://github.com/shashwatak/satellite-js) - Most popular JS library\n- [sgp4](https://www.npmjs.com/package/sgp4) - Alternative npm package\n\n**Rust**:\n- [sgp4](https://github.com/neuromorphicsystems/sgp4) - Primary Rust implementation\n- Other Rust libraries TBD\n\n**C++**:\n- [Vallado SGP4](https://celestrak.com/software/vallado-sw.php) - Reference C++ implementation\n- [libsgp4](https://github.com/dnwrnr/sgp4) - Alternative library\n\n**C#**:\n- [SGP.NET](https://github.com/parzivail/SGP.NET) - .NET port of Vallado's code\n- [Zeptomoby.OrbitTools](http://www.zeptomoby.com/satellites/) - Alternative .NET library\n\n### References\n- [Simplified General Perturbations #4 (SGP4)](https://en.wikipedia.org/wiki/Simplified_perturbations_models)\n- [Two-Line Element Set](https://en.wikipedia.org/wiki/Two-line_element_set)\n- [CelesTrak](https://celestrak.org/) - TLE data source\n- [NORAD SGP4 Standard](https://www.space-track.org/documentation#/sgp4)\n\n## Contact\n\n[To be determined]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcprosche%2Fvisibility-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcprosche%2Fvisibility-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcprosche%2Fvisibility-testing/lists"}