Skip to content

Commit 2c5a4c7

Browse files
authored
added thruster functionality to vortex utils to be able to reuse in controllers and thruster allocator (#50)
good
1 parent 605de73 commit 2c5a4c7

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

vortex_utils/include/vortex/utils/math.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,43 @@ Eigen::Quaterniond average_quaternions(
196196
*/
197197
Eigen::Quaterniond enu_ned_rotation(const Eigen::Quaterniond& quat);
198198

199+
/**
200+
* @brief Builds the 6×n thrust configuration matrix T for a set of thrusters.
201+
* As outlined in Fossen, 2021
202+
*
203+
* Column i maps thruster i's scalar force to a 6-DOF body-frame wrench:
204+
* rows 0-2 are the force direction, rows 3-5 are the moment (r × F) about the
205+
* centre of mass.
206+
*
207+
* @param thruster_force_direction 3×n matrix; each column is a unit force
208+
* direction vector in body frame.
209+
* @param thruster_position 3×n matrix; each column is the thruster
210+
* position in body frame.
211+
* @param center_of_mass Centre-of-mass position in body frame.
212+
* @return 6×n thrust configuration matrix T.
213+
*/
214+
Eigen::MatrixXd build_thrust_configuration_matrix(
215+
const Eigen::MatrixXd& thruster_force_direction,
216+
const Eigen::MatrixXd& thruster_position,
217+
const Eigen::Vector3d& center_of_mass);
218+
219+
/**
220+
* @brief Approximates the bounding box of the valid thrust region
221+
* polyhedron { T*u : u_min ≤ u ≤ u_max } using a greedy method.
222+
*
223+
* For each DOF i, greedily selects the thruster contribution that maximises
224+
* the wrench in that DOF, giving the per-DOF maximum achievable wrench.
225+
*
226+
* @param T 6×n thrust configuration matrix.
227+
* @param u_min Per-thruster minimum force vector (length n).
228+
* @param u_max Per-thruster maximum force vector (length n).
229+
* @return Vector of length T.rows() with the maximum wrench per DOF.
230+
*/
231+
Eigen::VectorXd calculate_valid_thrust_region_polyhedron(
232+
const Eigen::MatrixXd& T,
233+
const Eigen::VectorXd& u_min,
234+
const Eigen::VectorXd& u_max);
235+
199236
} // namespace vortex::utils::math
200237

201238
#endif // VORTEX_UTILS_MATH_HPP

vortex_utils/src/math.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,34 @@ Eigen::Quaterniond enu_ned_rotation(const Eigen::Quaterniond& quat) {
209209
return q_out.normalized();
210210
}
211211

212+
Eigen::MatrixXd build_thrust_configuration_matrix(
213+
const Eigen::MatrixXd& thruster_force_direction,
214+
const Eigen::MatrixXd& thruster_position,
215+
const Eigen::Vector3d& center_of_mass) {
216+
const int n = thruster_force_direction.cols();
217+
Eigen::MatrixXd T = Eigen::MatrixXd::Zero(6, n);
218+
for (int i = 0; i < n; i++) {
219+
const Eigen::Vector3d F = thruster_force_direction.col(i);
220+
const Eigen::Vector3d pos = thruster_position.col(i) - center_of_mass;
221+
T.block<3, 1>(0, i) = F;
222+
T.block<3, 1>(3, i) = pos.cross(F);
223+
}
224+
return T;
225+
}
226+
227+
Eigen::VectorXd calculate_valid_thrust_region_polyhedron(
228+
const Eigen::MatrixXd& T,
229+
const Eigen::VectorXd& u_min,
230+
const Eigen::VectorXd& u_max) {
231+
Eigen::VectorXd tau_max(T.rows());
232+
for (int i = 0; i < T.rows(); i++) {
233+
double w = 0.0;
234+
for (int j = 0; j < T.cols(); j++) {
235+
w += (T(i, j) > 0) ? T(i, j) * u_max(j) : T(i, j) * u_min(j);
236+
}
237+
tau_max(i) = w;
238+
}
239+
return tau_max;
240+
}
241+
212242
} // namespace vortex::utils::math

0 commit comments

Comments
 (0)