Skip to content

Henrik/velocity control#641

Closed
Henrimha wants to merge 118 commits intomainfrom
Henrik/velocity_control
Closed

Henrik/velocity control#641
Henrimha wants to merge 118 commits intomainfrom
Henrik/velocity_control

Conversation

@Henrimha
Copy link
Copy Markdown

Current status:
Implemented LQR regulator og solver.
Need to find/calculate system matrix and change solver
Made framework for PID regulator:
Need to tune parameters and find out why it is so slow and cant reach the reference
Made parameter and launch file
Need to change to getting parameters from global paramter file and not local
The regulator communicates with the rest of the system

Next steps:
Get a model of the system, the A matrix
Tune and fix the PID
Make a better solution for swapping control types
Change LQR solver, alternatively make myself, can retry DRAKE
Implement MPC
Further goals:
Improve system for getting parameters, make them into lists and not single values
Implement a reset off the controller
Change it into a lifecycle Node

Copy link
Copy Markdown
Member

@chrstrom chrstrom left a comment

Choose a reason for hiding this comment

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

See that this is still in draft, but a few comments to include with the rest of the TODOs before publishing 💯

integral_yaw=0.0;
};
*/
class LQRparameters {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would make this a struct (usually call these "POD" structs (Plain Old Data))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(Goes for everywhere else as well, not gonna add review comments in the other places)

Comment on lines +98 to +108
double q_surge;
double q_pitch;
double q_yaw;
double r_surge;
double r_pitch;
double r_yaw;
double i_surge;
double i_pitch;
double i_yaw;
double i_weight;
double max_force;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just hold an LQRparameters object?

Also: I'd initialize all the members here, just to avoid the potential error of using an uninitialized variable (i.e. type var{}; instead of type var;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(Goes for everywhere else as well, not gonna add review comments in the other places)


// VariablesEigen::Matrix3d vector_to_matrix3d(const std::vector<double>
// &other_matrix)
const double pi = 3.14159265358979323846;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

std::numbers::pi or M_PI

Comment on lines +7 to +13
class angle {
public:
double phit = 0.0;
double thetat = 0.0;
double psit = 0.0;
};
angle quaternion_to_euler_angle(double w, double x, double y, double z);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Andeshog vortex-utils?

Comment on lines +13 to +14

class test_VC : public rclcpp::Node {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should keep to a ConsistentStyle here and a few other places

Comment on lines +153 to +155
std::tie(surge_windup, force_x) = saturate(u[0], surge_windup, max_force);
std::tie(pitch_windup, torque_y) = saturate(u[1], pitch_windup, max_force);
std::tie(yaw_windup, torque_z) = saturate(u[2], yaw_windup, max_force);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Think you can use structured bindings here instead of std::tie

Comment on lines +113 to +122
augmented_system_matrix << system_matrix(0, 0), system_matrix(0, 1),
system_matrix(0, 2), 0, 0, 0, system_matrix(1, 0), system_matrix(1, 1),
system_matrix(1, 2), 0, 0, 0, system_matrix(2, 0), system_matrix(2, 1),
system_matrix(2, 2), 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
0, -1, 0, 0, 0;
augmented_input_matrix << inertia_matrix_inv(0, 0),
inertia_matrix_inv(0, 1), inertia_matrix_inv(0, 2), 0, 0, 0,
inertia_matrix_inv(1, 0), inertia_matrix_inv(1, 1),
inertia_matrix_inv(1, 2), 0, 0, 0, inertia_matrix_inv(2, 0),
inertia_matrix_inv(2, 1), inertia_matrix_inv(2, 2), 0, 0, 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You should be able to initialize this with ::Zero() then use .topLeftCorner<>, .bottomLeftCorner<> and .leftCols<> block operations to set the non-zero blocks. Arguably easier to read that way

Comment on lines +185 to +189
extern "C" {
// Fortran subroutine for solving symplectic Schur decomposition(double
// precision version)
void sb02mt_(const char* JOBG,
const char* JOBL,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Genuine curiosity, where did this come from? (If you still want to keep the online solver, Eigen supports LDLT out-of-the-box. Alternatively, you could make a separate solver that runs entirely offline or just once during construction?)

Comment on lines +325 to +356
Eigen::Matrix3d vector_to_matrix3d(const std::vector<double>& other_matrix) {
Eigen::Matrix3d mat;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
mat(i, j) = other_matrix[i * 3 + j];
return mat;
}
std::vector<double> matrix3d_to_vector(const Eigen::Matrix3d& mat) {
std::vector<double> other_matrix(9);
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
other_matrix[i * 3 + j] = mat(i, j);
return other_matrix;
}

std::vector<std::vector<double>> matrix3d_to_vector2d(
const Eigen::Matrix3d& mat) {
std::vector<std::vector<double>> other_matrix(3, std::vector<double>(3));
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
other_matrix[i][j] = mat(i, j);
return other_matrix;
}

Eigen::Matrix3d vector2d_to_matrix3d(
const std::vector<std::vector<double>>& other_matrix) {
Eigen::Matrix3d mat;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
mat(i, j) = other_matrix[i][j];
return mat;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd use Eigen::Map to avoid needing any loops here.

Just a few things you'd want to look out for though:

  1. You are implying a "correct" size for the input vector - this should be checked (constexpr'd / static-asserted if possible)
  2. Would you want to support both row-major and column-major? If not, might be good to specify.

Comment on lines +1 to +2
cmake_minimum_required(VERSION 3.8)
project(velocity_controller)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the top-level CMakeLists: There should be some slides somewhere in the C++ learning materials that covers this, but TLDR:

  1. Build non-ros code as a library that can be linked into the ros/test executables
  2. Would be nice to have a separate cmakelists for src (non-ros), src (ros) and tests
  3. You should only build tests if -DBUILD_TESTING is ON/True

anbit-adhi and others added 28 commits March 16, 2026 13:13
…set function in LQR, and added OMM to launch file
@jorgenfj
Copy link
Copy Markdown
Contributor

#697 moved here

@jorgenfj jorgenfj closed this Mar 28, 2026
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.

6 participants