Skip to content

Tmp/reference filter quat#688

Merged
jorgenfj merged 11 commits into
feat/reference-filter-quatfrom
tmp/reference-filter-quat
Mar 28, 2026
Merged

Tmp/reference filter quat#688
jorgenfj merged 11 commits into
feat/reference-filter-quatfrom
tmp/reference-filter-quat

Conversation

@jorgenfj

Copy link
Copy Markdown
Contributor

Reference filter that uses an error state formulation to get around the singularities of euler/RPY.
Added sim test to verify implementation is correct. Sim test can eventually be incorporated with quat controllers to test 90 degree pitch scenarios.

I created a temp branch for this PR for review purposes to easier highlight the differences between this implementation and the original reference filter implementation.

@jorgenfj jorgenfj requested a review from Andeshog March 21, 2026 21:57
@codecov

codecov Bot commented Mar 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.29534% with 94 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (feat/reference-filter-quat@2d347c2). Learn more about missing BASE report.

Files with missing lines Patch % Lines
..._filter_dp_quat/ros/reference_filter_ros_utils.hpp 0.00% 31 Missing ⚠️
...ce_filter_dp_quat/src/ros/reference_filter_ros.cpp 0.00% 27 Missing ⚠️
...erence_filter_dp_quat/test/test_waypoint_utils.cpp 67.85% 0 Missing and 18 partials ⚠️
...nce_filter_dp_quat/test/test_waypoint_follower.cpp 50.00% 0 Missing and 11 partials ⚠️
...rence_filter_dp_quat/src/lib/waypoint_follower.cpp 84.44% 6 Missing and 1 partial ⚠️
Additional details and impacted files
@@                      Coverage Diff                      @@
##             feat/reference-filter-quat     #688   +/-   ##
=============================================================
  Coverage                              ?   37.96%           
=============================================================
  Files                                 ?       82           
  Lines                                 ?     5750           
  Branches                              ?     1763           
=============================================================
  Hits                                  ?     2183           
  Misses                                ?     3107           
  Partials                              ?      460           
Flag Coverage Δ
unittests 37.96% <51.29%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...eference_filter_dp_quat/src/lib/waypoint_utils.cpp 97.05% <100.00%> (ø)
...rence_filter_dp_quat/src/lib/waypoint_follower.cpp 87.71% <84.44%> (ø)
...nce_filter_dp_quat/test/test_waypoint_follower.cpp 80.64% <50.00%> (ø)
...erence_filter_dp_quat/test/test_waypoint_utils.cpp 68.91% <67.85%> (ø)
...ce_filter_dp_quat/src/ros/reference_filter_ros.cpp 0.00% <0.00%> (ø)
..._filter_dp_quat/ros/reference_filter_ros_utils.hpp 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jorgenfj jorgenfj requested a review from Q3rkses March 25, 2026 22:11

@Q3rkses Q3rkses left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, maybe we need to tune reference filter seperately for nautilus as it isnt quite as fast as orca

Comment on lines +32 to +39
extra_params = {}
if rpy_publish:
extra_params = {
"publish_rpy_debug": True,
"topics.guidance.dp_rpy": "guidance/dp",
"topics.guidance.dp": "guidance/dp_quat",
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like you kept both functionalities. I'm not sure if the reference filter itself will ever experience gimbal lock, but it is nice that we can publish straight quat and operate on quat errors instead of doing quat2euler.

Comment on lines +88 to 96
Eigen::Vector6d WaypointFollower::velocity() const {
std::lock_guard<std::mutex> lock(mutex_);
return state_.segment<6>(6);
}

Pose WaypointFollower::waypoint_goal() const {
std::lock_guard<std::mutex> lock(mutex_);
state_.head<6>() = reference_goal_;
return waypoint_goal_;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented same on anbit, we usually lock but dont explicitly unlock mutexes, i guess they unlock themselves when exiting current scope but maybe for readability we should explicitly unlock them

break;
}

return reference_out;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change from reference to waypoint

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes it easier for non-control people to understand😅
So they don't mix the waypoint with current reference values being published

Comment on lines +60 to +68
publish_rpy_debug_ = this->declare_parameter<bool>("publish_rpy_debug");
if (publish_rpy_debug_) {
std::string rpy_topic = this->declare_parameter<std::string>(
"topics.guidance.dp_rpy", guidance_topic + "_rpy");
rpy_debug_pub_ =
this->create_publisher<vortex_msgs::msg::ReferenceFilter>(
rpy_topic, qos_sensor_data);
spdlog::info("RPY debug publisher enabled on topic: {}", rpy_topic);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe instead of using publish_rpy_debug as a flag only publish it when it is built in debug mode.

I.e colcon build --cmake-args -DCMAKE_BUILD_TYPE=Debug

and putting this near the top of the file
#ifdef NDEBUG
constexpr bool debug = false; // Release
#else
constexpr bool debug = true; // Debug
#endif

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am planning on removing this in favor of just using the util node

Comment on lines +51 to +60
1. **Compute reference error** — The 6D reference $r$ is the error between the waypoint goal and the nominal pose:
- $r_{0:3} = p_{goal} - p_{nominal}$
- $r_{3:6} = \text{quaternion\_error}(q_{nominal},\ q_{goal})$

The `quaternion_error` function returns $2 \cdot \text{vec}(q_{nominal}^{-1} \otimes q_{goal})$, which for small angles approximates the rotation vector from nominal to goal.

2. **Integrate** — The standard filter step:
```math
\dot{x} = A_d x + B_d r, \quad x \leftarrow x + \dot{x} \cdot dt
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something here didnt work correctly when i try to view it as md on github

pose: PoseData = PoseData()
pose.x = random.uniform(-10.0, 10.0)
pose.y = random.uniform(-10.0, 10.0)
pose.z = random.uniform(0.5, 3.0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should make default test scenario with no seabed, and then we are no longer constricted by depth

super().__init__('reference_filter_quat_waypoint_client')

self._action_client = ActionClient(
self, ReferenceFilterQuatWaypoint, '/orca/reference_filter'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orca?

def __init__(self):
super().__init__('check_goal_node')
self.pose_sub_ = self.create_subscription(
PoseWithCovarianceStamped, '/orca/pose', self.pose_callback, best_effort_qos

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orca? maybe resolve with param

@jorgenfj jorgenfj force-pushed the tmp/reference-filter-quat branch from 793789f to fa5a167 Compare March 28, 2026 13:12
@jorgenfj jorgenfj merged commit 296e8d6 into feat/reference-filter-quat Mar 28, 2026
1 of 6 checks passed
@jorgenfj jorgenfj deleted the tmp/reference-filter-quat branch March 28, 2026 13:32
jorgenfj added a commit that referenced this pull request Mar 28, 2026
* init package structure

* Tmp/reference filter quat (#688)

* update waypoint utils to quat

* refernce filter quat implementation

* RPY reference testing publisher

* sim test for quat ref filter

* update pkg maintainer :)

* add reference quat sim test to workflow

* helpers for step function

* fix readme

* ref_quat remove waypoint_utils and ref feedback

* remove RPY debug publisher

* pre-commit

* update sim test

* fix sim test

* separate reference_filter_quat topic

* ref quat to euler converter for sim test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants