Skip to content
Merged
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
22 changes: 22 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Check

on:
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Build
run: bun run build
365 changes: 198 additions & 167 deletions astro.config.mjs

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/starlight": "^0.37.7",
"@astrojs/starlight": "^0.40.0",
"@fontsource-variable/jetbrains-mono": "^5.2.8",
"@fontsource-variable/space-grotesk": "^5.2.10",
"astro": "^5.18.0",
"astro": "^6.4.7",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"sharp": "^0.34.5"
"sharp": "^0.34.5",
"starlight-links-validator": "^0.24.1"
}
}
110 changes: 110 additions & 0 deletions src/components/SocialIcons.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
import config from 'virtual:starlight/user-config';
import { Icon } from '@astrojs/starlight/components';

const links = config.social || [];
---

{
links.length > 0 && (
<>
{links.map(({ label, href, icon }) => {
if (icon === 'github') {
return (
<div class="github-dropdown-container">
<button class="github-dropdown-btn" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">{label}</span>
<Icon name={icon} />
<Icon name="down-caret" class="caret" />
</button>
<div class="github-dropdown-menu">
<a href="https://github.com/umrover/mrover-ros2" target="_blank" rel="noopener noreferrer">
ROS2
</a>
<a href="https://github.com/umrover/mrover-esw" target="_blank" rel="noopener noreferrer">
ESW
</a>
<a href="https://github.com/umrover/mrover-drone" target="_blank" rel="noopener noreferrer">
Drone
</a>
</div>
</div>
);
}
return (
<a {href} rel="me" class="sl-flex">
<span class="sr-only">{label}</span>
<Icon name={icon} />
</a>
);
})}
</>
)
}

<style>
@layer starlight.core {
a, .github-dropdown-btn {
color: var(--sl-color-text-accent);
padding: 0.5em;
margin: -0.5em;
background: none;
border: none;
cursor: pointer;
display: inline-flex;
align-items: center;
}
a:hover, .github-dropdown-btn:hover {
opacity: 0.66;
}
.github-dropdown-container {
position: relative;
display: inline-flex;
align-items: center;
}
.github-dropdown-btn {
gap: 0.2em;
}
.github-dropdown-btn :global(svg.caret) {
width: 12px;
height: 12px;
opacity: 0.8;
transition: transform 0.2s ease;
}
.github-dropdown-container:hover .github-dropdown-btn :global(svg.caret) {
transform: rotate(180deg);
}
.github-dropdown-menu {
display: none;
position: absolute;
top: calc(100% + 0.5rem);
right: 0;
background-color: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 0.5rem;
box-shadow: var(--sl-shadow-md);
min-width: max-content;
z-index: 1000;
padding: 0.375rem 0;
}
.github-dropdown-container:hover .github-dropdown-menu,
.github-dropdown-container:focus-within .github-dropdown-menu {
display: block;
}
.github-dropdown-menu a {
display: block;
padding: 0.5rem 1.25rem;
margin: 0;
color: var(--sl-color-text);
text-decoration: none;
font-size: var(--sl-text-sm);
font-weight: 700;
transition: background-color 0.15s ease, color 0.15s ease;
}
.github-dropdown-menu a:hover {
background-color: var(--sl-color-bg-hover);
color: var(--sl-color-text-accent);
opacity: 1;
}
}
</style>
39 changes: 39 additions & 0 deletions src/content/docs/archive/projects/2024-projects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "2024 Projects"
---
## Perception

* [Long range ArUco tag detection](/autonomy/perception/long-range-tag-detection)
* [Object detection](/autonomy/perception/object-detection)
* [Surface normals costmap](/autonomy/navigation/surface-normals-costmap)
* Spatial mapping for teleop
* [Lander auto-align](/autonomy/navigation/lander-auto-align)

## Navigation

* [Approach Target Base State](/autonomy/navigation/approach-target-base-state)
* [Second Camera Navigation Integration (LongRangeState)](/autonomy/navigation/second-camera-integration)
* [ApproachObjectState](/autonomy/navigation/approach-object-state)
* [Obstacle Avoidance](/autonomy/navigation/obstacle-avoidance)
* [Adaptive pure pursuit](/autonomy/navigation/adaptive-pure-pursuit)
* [URC vs. CIRC switch](/general-resources/devops/urc-vs-circ-switch)

## Localization

* Real-time kinematic positioning
* Dual GNSS Heading
* IMU Setup
* Tip Detection

## ESW

* Hardware accelerated and robust camera streaming
* Brushed motor controller STM
* Brushed motor controller ROS
* Brushless ROS
* Science controller STM
* PDB STM

## Teleop
* Convert to Django
* [5dof IK](/autonomy/navigation/5dof-ik)
30 changes: 30 additions & 0 deletions src/content/docs/archive/projects/2025-2026-projects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "2025-2026 Projects"
---
## Perception
* [Key-Detection](/autonomy/perception/key-detection)
* [Object Detector Model](/autonomy/perception/object-detector-model)
* [Light Detector](/autonomy/perception/light-detector)

## Navigation

* [Arm IK](/autonomy/navigation/arm-ik)
* [Click IK](/autonomy/navigation/click-ik)
* [Path Execution](/autonomy/navigation/path-execution)

## Localization

* [Localisation Caching State Machine](/autonomy/localization/data-caching-state-machine)
* [Invariant EKF](/autonomy/localization/invariant-ekf)
* [Dual Antenna RTK](/autonomy/localization/dual-antenna-rtk)
* Directional Antenna (RAT)

## ESW

* Hardware accelerated and robust camera streaming
* Science Board STM
* CANalyzer

## Teleop
* Convert to Django
* [5dof IK](/autonomy/navigation/5dof-ik)
4 changes: 0 additions & 4 deletions src/content/docs/autonomy/drone.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Key properties:
### IEKF: using RTK heading as a measurement
The IEKF fuses dual‑antenna RTK heading as a yaw measurement. It gates out invalid data, converts the heading into a body‑frame reference vector, builds a measurement model, and runs the EKF correction step weighted by `rtk_heading_noise`.

```302:330:localization/iekf_se3/iekf_se3.cpp
```cpp
void IEKF_SE3::rtk_heading_callback(const mrover::msg::Heading::ConstSharedPtr &rtk_heading, const mrover::msg::FixStatus::ConstSharedPtr &rtk_heading_status) {

if (rtk_heading_status->fix_type.fix == mrover::msg::FixType::NO_SOL) {
Expand Down Expand Up @@ -104,7 +104,7 @@ Tip: Tune `iekf_se3.rtk_heading_noise` in `config/localization.yaml` to balance
### Heading filter: correcting IMU yaw when RTK heading is FIXED
This node applies a 1D Kalman filter to correct yaw using dual‑antenna heading only when the heading solution is `FIXED` (highest quality). It computes the uncorrected yaw from the IMU quaternion, forms an angle error to the measured RTK heading, then predict–corrects the scalar filter.

```71:99:localization/heading_filter/heading_filter.cpp
```cpp
void HeadingFilter::sync_rtk_heading_callback(const mrover::msg::Heading::ConstSharedPtr &heading, const mrover::msg::FixStatus::ConstSharedPtr &heading_status) {


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "Invariant EKF"

![kalman-filters](https://github.com/user-attachments/assets/5ca4b400-f543-476f-bfe2-b379f7876e5a)

Please read over the Kalman Filter and Sensor Fusion section of the [Localization](/localization/overview) page and view the additional resources before starting here. The Extended Kalman Filter (EKF) is a version of the Kalman filter adapted for nonlinear systems, and is the standard used in navigation systems today. Instead of representing process dynamics through a constant matrix, which is only suitable for linear processes, the EKF uses the Jacobian of the process dynamics model. Evaluated at the current state, it provides a local linear approximation for an otherwise nonlinear process. This approximation is then used in the regular Kalman filter as matrix $A$. You can think of this as similar to a tangent line approximation you may have done in calculus.
Please read over the Kalman Filter and Sensor Fusion section of the [Localization](/autonomy/localization/overview) page and view the additional resources before starting here. The Extended Kalman Filter (EKF) is a version of the Kalman filter adapted for nonlinear systems, and is the standard used in navigation systems today. Instead of representing process dynamics through a constant matrix, which is only suitable for linear processes, the EKF uses the Jacobian of the process dynamics model. Evaluated at the current state, it provides a local linear approximation for an otherwise nonlinear process. This approximation is then used in the regular Kalman filter as matrix $A$. You can think of this as similar to a tangent line approximation you may have done in calculus.

Highly recommend checking out these resources for a more detailed explanation and algorithm equations:
* https://en.wikipedia.org/wiki/Extended_Kalman_filter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Localization"
---
# What is Localization?
In simple terms, localization is just figuring out where the robot is. In the case of our rover, we need to know what point it is located at in 3D space, as well as what angle it is rotated to in each axis. This information is also known as a pose (see [this](/autonomy/3d-poses-transforms-rotations) page). We need to have this data at all times, and it needs to be updated frequently enough to keep up with the rover's motion. We typically estimate this data by measuring it with a variety of sensors and then processing that sensor data with a variety of fusion and filtering algorithms to make it more accurate.
In simple terms, localization is just figuring out where the robot is. In the case of our rover, we need to know what point it is located at in 3D space, as well as what angle it is rotated to in each axis. This information is also known as a pose (see [this](/autonomy/resources/3d-poses-transforms-rotations) page). We need to have this data at all times, and it needs to be updated frequently enough to keep up with the rover's motion. We typically estimate this data by measuring it with a variety of sensors and then processing that sensor data with a variety of fusion and filtering algorithms to make it more accurate.

# Sensors
## GPS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ Also the rules specify two new waypoints during the Autonomy mission that requir
**Rough Steps**:
1. Learn how the new state machine library works. The code new code is merged into [master](https://github.com/umrover/mrover-ros). The files for the library are in src/util/state_lib and the updated states are in src/navigation. Some other examples of how to use the library are in test/util/state_lib.
2. Review the outlines of the new states in the ENGIN|MRover/Software/Auton/New States folder in the shared drive. These outlines don't contain all the code you need, make sure to reference the already implemented ApproachPostState for what other things you may need to add.
3. Start coding up the outline of the ApproachTargetBaseState. After everyone understands this state, split into smaller groups to work on the ApproachPostState, [LongRangeState](/navigation/second-camera-integration), and [ApproachObjectState](/navigation/approach-object-state) states.
3. Start coding up the outline of the ApproachTargetBaseState. After everyone understands this state, split into smaller groups to work on the ApproachPostState, [LongRangeState](/autonomy/navigation/second-camera-integration), and [ApproachObjectState](/autonomy/navigation/approach-object-state) states.
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ The current IK implementation has not been fully tested on the rover, so it is n

# Solution

The end effector has a limited range of motion, particularly in terms of pitch. This means that it is not always possible to make the end effector parallel to the ground (as we would like to, especially for typing) for all arm positions. Thus it is necessary to determine the bubble of positions that are reachable with the end effector level, so that we can optimally position the rover for typing. More details on finding this "bubble" can be found [here](/navigation/arm-ik-testing).
The end effector has a limited range of motion, particularly in terms of pitch. This means that it is not always possible to make the end effector parallel to the ground (as we would like to, especially for typing) for all arm positions. Thus it is necessary to determine the bubble of positions that are reachable with the end effector level, so that we can optimally position the rover for typing. More details on finding this "bubble" can be found [here](/autonomy/navigation/arm-ik-testing).
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ title: "Costmap Path Planning"
Here's a (simplified) overview of the navigation state machine as it is now:
![Nav State Machine (Simplified)](https://github.com/user-attachments/assets/61738dfe-3728-46dc-a952-79b7d9e571ce)

For more details on the specifics of how the current costmap implementation works, be sure to check out [this](/navigation/obstacle-avoidance) page.
For more details on the specifics of how the current costmap implementation works, be sure to check out [this](/autonomy/navigation/obstacle-avoidance) page.
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,44 @@ title: "Navigation"

## Contents

1. [State Machine Diagram](#State-machine-diagram)
2. [What is a State Machine and why do we use a custom implementation?](#What-is-a-State-Machine-and-why-do-we-use-a-custom-implementation?)
3. [State Descriptions](#State-Descriptions)
1. [State Machine Diagram](#state-machine-diagram)
2. [What is a State Machine and why do we use a custom implementation?](#what-is-a-state-machine-and-why-do-we-use-a-custom-implementation)
3. [State Descriptions](#state-descriptions)

3.1 [Off State](#Off-State)
3.1 [Off State](#off-state)

3.2 [Done State](#Done-State)
3.2 [Done State](#done-state)

3.3 [Waypoint State](#Waypoint-State)
3.3 [Waypoint State](#waypoint-state)

3.4 [Approach Target State](#Approach-Target-State)
3.4 [Approach Target State](#approach-target-state)

3.5 [Long Range State](#Long-Range-State)
3.5 [Long Range State](#long-range-state)

3.6 [Costmap Search State](#Costmap-Search-State)
3.6 [Costmap Search State](#costmap-search-state)

3.7 [Backup State](#Backup-State)
3.7 [Backup State](#backup-state)

3.8 [Stuck Recovery State](#Stuck-Recovery-State)
3.8 [Stuck Recovery State](#stuck-recovery-state)

4. [Path Planning](#Path-Planning)
4. [Path Planning](#path-planning)
4.1 [A* Algorithm](#a-algorithm)
4.2 [Costmap Integration](#costmap-integration)
4.2 Costmap Integration

5. [Context, Rover, Environment, Course](#Context,-Rover,-Environment,-Course)
5. [Context, Rover, Environment, Course](#context-rover-environment-course)

5.1 [Context](#Context-Functions/Attributes)
5.1 [Context](#context-functionsattributes)

5.2 [Rover](#Rover)
5.2 [Rover](#rover)

5.3 [Environment](#Environment)
5.3 [Environment](#environment)

5.4 [Course](#Course)
5.4 [Course](#course)

6. [DriveController Class](#DriveController-Class)
7. [Trajectory](#Trajectory)
8. [SearchTrajectory](#SearchTrajectory)
9. [ArmController](#armcontroller)
6. [DriveController Class](#drivecontroller-class)
7. [Trajectory](#trajectory)
8. [SearchTrajectory](#searchtrajectory)
9. [ArmController](#arm-controller)


## State machine diagram
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ Last year A* was implemented into the rover's path planning logic providing us w
During the auton mission, we are limited on time. As such, we need to drive in a way that will save us the most time possible.

# **Solutions**
## [Pure Pursuit](/navigation/pure-pursuit)
Currently, our path-tracking algorithm is built around a state machine that limits the rover's driving to essentially two states -- turn in place and drive forward (read more [here](/navigation/overview) ). This is problematic since A*'s path is often quite jagged, meaning the rover is constantly stopping and turning in place to try to follow this path. To solve this, we will utilize a pure pursuit algorithm, which will eliminate the turn in place/drive forward behavior entirely. More details can be found at the page linked above.
## [Pure Pursuit](/autonomy/navigation/pure-pursuit)
Currently, our path-tracking algorithm is built around a state machine that limits the rover's driving to essentially two states -- turn in place and drive forward (read more [here](/autonomy/navigation/overview) ). This is problematic since A*'s path is often quite jagged, meaning the rover is constantly stopping and turning in place to try to follow this path. To solve this, we will utilize a pure pursuit algorithm, which will eliminate the turn in place/drive forward behavior entirely. More details can be found at the page linked above.

## [Path Smoothing](/navigation/path-smoothing)
## [Path Smoothing](/autonomy/navigation/path-smoothing)
One level above the rover's path-tracking is its path planning. As mentioned above, A*'s paths are quite jagged, and while the implementation of pure pursuit will generally smooth out the rover's traversal, we are also seeking to process and smooth out the A* trajectory before we begin to track it. This will reduce unnecessary oscillations and sharp turns, leading to a more efficient, natural, and stable trajectory for the rover to follow. As such, we will incorporate some form of path smoothing, either with relaxation, interpolation, or both, into the path planning process. More details can be found at the page linked above.

## [Inward Spiraling](/navigation/inward-spiraling)
As detailed in the [navigation wiki](/navigation/overview), the high-level decision-making for the rover's navigation is based off of a state machine. In the search state, we currently spiral from a center waypoint outwards within some radius. However, this is not optimal if we are driving to the center waypoint from outside of the search area's radius. Instead, rather than driving from outside of the search area to its center and spiraling back to the edge, we should start spiraling _inwards_ from the edge of the search area towards the center waypoint.
## [Inward Spiraling](/autonomy/navigation/inward-spiraling)
As detailed in the [navigation wiki](/autonomy/navigation/overview), the high-level decision-making for the rover's navigation is based off of a state machine. In the search state, we currently spiral from a center waypoint outwards within some radius. However, this is not optimal if we are driving to the center waypoint from outside of the search area's radius. Instead, rather than driving from outside of the search area to its center and spiraling back to the edge, we should start spiraling _inwards_ from the edge of the search area towards the center waypoint.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: "Long Range Tag Detection"
> The 3 posts will have GNSS coordinates that are within the vicinity of the posts,
increasing in range from approximately 5-20 m.

Please also read the Wiki page on [perception](/perception/overview).
Please also read the Wiki page on [perception](/autonomy/perception/overview).

**Problem**: The [ZED stereo camera](https://www.stereolabs.com/zed-2/) can only detect tags around 8 meters away. As such we have to run a spiral search to find the tag. This takes precious time since the autonomy period is only 30 minutes long.

Expand Down
Loading