rm_vision/tests/gimbal_response_test.cpp
2025-12-15 02:33:20 +08:00

165 lines
4.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <chrono>
#include <nlohmann/json.hpp>
#include <opencv2/opencv.hpp>
#include <thread>
#include "io/cboard.hpp"
#include "io/command.hpp"
#include "tools/exiter.hpp"
#include "tools/logger.hpp"
#include "tools/math_tools.hpp"
#include "tools/plotter.hpp"
using namespace std::chrono_literals;
const std::string keys =
"{help h usage ? | | 输出命令行参数说明}"
"{delta-angle a | 8 | yaw轴delta角}"
"{circle c | 0.2 | delta_angle的切片数}"
"{signal-mode m | triangle_wave | 发送信号的模式}"
"{axis x | yaw | 发送信号的轴}"
"{@config-path | configs/sentry.yaml | 位置参数yaml配置文件路径 }";
double yaw_cal(double t)
{
double A = 7;
double T = 4; // s
return A * std::sin(2 * M_PI * t / T); // 31是云台yaw初始角度单位为度
}
double pitch_cal(double t)
{
double A = 7;
double T = 4; // s
return A * std::sin(2 * M_PI * t / T + M_PI / 2) + 18; // 18是云台pitch初始角度单位为度
}
int main(int argc, char * argv[])
{
cv::CommandLineParser cli(argc, argv, keys);
auto config_path = cli.get<std::string>(0);
auto delta_angle = cli.get<double>("delta-angle");
auto circle = cli.get<double>("circle");
auto signal_mode = cli.get<std::string>("signal-mode");
auto axis = cli.get<std::string>("axis");
if (cli.has("help") || config_path.empty()) {
cli.printMessage();
return 0;
}
tools::Exiter exiter;
tools::Plotter plotter;
io::CBoard cboard(config_path);
auto init_angle = 0;
double slice = circle * 100; //切片数=周期*帧率
auto dangle = delta_angle / slice;
double cmd_angle = init_angle;
int axis_index = axis == "yaw" ? 0 : 1; // 0 for yaw, 1 for pitch
double error = 0;
int count = 0;
io::Command init_command{1, 0, 0, 0};
cboard.send(init_command);
std::this_thread::sleep_for(5s); //等待云台归零
io::Command command{0};
io::Command last_command{0};
double t = 0;
auto last_t = t;
double dt = 0.005; // 5ms, 模拟200fps
auto t0 = std::chrono::steady_clock::now();
while (!exiter.exit()) {
nlohmann::json data;
auto timestamp = std::chrono::steady_clock::now();
std::this_thread::sleep_for(1ms);
Eigen::Quaterniond q = cboard.imu_at(timestamp);
Eigen::Vector3d eulers = tools::eulers(q, 2, 1, 0);
if (signal_mode == "triangle_wave") {
if (count == slice) {
cmd_angle = init_angle;
command = {1, 0, 0, 0};
if (axis_index == 0)
command.yaw = cmd_angle / 57.3;
else
command.pitch = cmd_angle / 57.3;
count = 0;
} else {
cmd_angle += dangle;
if (axis_index == 0)
command.yaw = cmd_angle / 57.3;
else
command.pitch = cmd_angle / 57.3;
count++;
}
cboard.send(command);
if (axis_index == 0) {
data["cmd_yaw"] = command.yaw * 57.3;
data["last_cmd_yaw"] = last_command.yaw * 57.3;
data["gimbal_yaw"] = eulers[0] * 57.3;
} else {
data["cmd_pitch"] = command.pitch * 57.3;
data["last_cmd_pitch"] = last_command.pitch * 57.3;
data["gimbal_pitch"] = eulers[1] * 57.3;
}
data["t"] = tools::delta_time(std::chrono::steady_clock::now(), t0);
last_command = command;
plotter.plot(data);
std::this_thread::sleep_for(8ms); //模拟自瞄100fps
}
else if (signal_mode == "step") {
if (count == 300) {
cmd_angle += delta_angle;
count = 0;
}
command = {1, 0, tools::limit_rad(cmd_angle / 57.3), 0};
count++;
cboard.send(command);
data["cmd_yaw"] = command.yaw * 57.3;
data["last_cmd_yaw"] = last_command.yaw * 57.3;
data["gimbal_yaw"] = eulers[0] * 57.3;
last_command = command;
plotter.plot(data);
std::this_thread::sleep_for(8ms); //模拟自瞄100fps
}
else if (signal_mode == "circle") {
std::cout << "t: " << t << std::endl;
command.yaw = yaw_cal(t) / 57.3;
command.pitch = pitch_cal(t) / 57.3;
command.control = 1;
command.shoot = 0;
t += dt;
if (t - last_t > 2) {
t += 2.4;
last_t = t;
}
cboard.send(command);
data["t"] = t;
data["cmd_yaw"] = command.yaw * 57.3;
data["cmd_pitch"] = command.pitch * 57.3;
data["gimbal_yaw"] = eulers[0] * 57.3;
data["gimbal_pitch"] = eulers[1] * 57.3;
plotter.plot(data);
std::this_thread::sleep_for(9ms);
}
}
return 0;
}