0
0
Files
build/control/control.cpp

1094 lines
37 KiB
C++
Raw Permalink Normal View History

/*******************************************************************************
* 仿
*
* 仿
*
* Created on: 2023-3-9
******************************************************************************/
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <cstring>
#include <errno.h>
#include <poll.h>
#include <thread>
#include <iostream>
#include <vector>
#include <map>
#include <memory>
#include <atomic>
#include <mutex>
#include <csignal>
#include <chrono>
// 包含现有的硬件仿真头文件
#include "sensor_gnss.h"
#include "sensor_tx2.h"
#include "sensor_optical.h"
#include "sensor_mems.h"
#include "sensor_gyro.h"
#include "sensor_wheel.h"
#include "sensor_star.h"
#include "sensor_thrust.h"
#include "orbit_info.h"
#include "GNCFunction.h"
#include "liblog.h"
using namespace std;
// ==================================== 全局仿真数据结构 ====================================
// 轨道参数
static double TarRVECI[6] = {23621367.9190000, -34592141.8670000, 3657159.91500000,
2548.34575500000, 1736.43994900000, -5.86735000000000};
static double ChaRVECI[6] = {23580586.0537251, -34621080.4670552, 3658341.81666531,
2550.44489430168, 1733.51288095298, -5.46126675290179};
static double AttiVelECI[3] = {0.0, 0.0, 0.0};
static double EulerVVLH[3] = {0.0, 0.0, 0.0};
static double MtxVVLH2Body[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
static double MtxECI2VVLH[3][3] = {{0.8266, 0.5628, -0.0018},
{0.0474, -0.0729, -0.9962},
{-0.5608, 0.8234, -0.087}};
static double QuatECI[4] = {1.0, 0.0, 0.0, 0.0};
static double mjd = 60776.00480324;
static double Epoch2017 = 261130015.0;
// 光电/TX2相关参数
static int TargetFLAG = 0; // 1:左帆板, 0:本体
static double R_Plane[2] = {0.0, 0.0};
static double LOS_Remote[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
// 硬件状态
struct HardwareStatus {
atomic<uint8_t> gnss_onoff{1};
atomic<uint8_t> star_onoff{1};
atomic<uint8_t> gyro_onoff{1};
atomic<uint8_t> mems_onoff{1};
atomic<uint8_t> wheel_onoff{1};
atomic<uint8_t> optical_onoff{1};
atomic<uint8_t> carried_status{0}; // 0:运载模式, 2:独立模式
// 动量轮
double WheelTorqueBody[3] = {0.0, 0.0, 0.0};
double WheelAM[3] = {0.0, 0.0, 0.0};
double CmdWheel[3] = {0.0, 0.0, 0.0};
// 推进
double ThrustTorque[3] = {0.0, 0.0, 0.0};
double SatMtxI[3][3] = {{10.0, 0.0, 0.0}, {0.0, 10.0, 0.0}, {0.0, 0.0, 10.0}};
double ThrustForce[3] = {0.0, 0.0, 0.0};
double CmdJetPWM[12] = {0.0};
double JetPWMPlan[12] = {0.0};
double SatMass = 100.0; // kg
// 载荷
atomic<int> LaunchFlag1{0};
atomic<int> LaunchFlag2{0};
atomic<int> LaunchAlreadyFlag1{0};
atomic<int> LaunchAlreadyFlag2{0};
};
// 数据帧缓冲区
static uint8_t gnss_frame[GPS_Hk_FRAME_LENGTH];
static uint8_t xgd_frame[OPTIC_FRAME_LENGTH];
static uint8_t tx2_frame[VISION_Info_Length];
static uint8_t wheel_frame[WHEEL_FRAME_LENGTH];
static uint8_t gyro_frame[GYRO_FRAME_LENGTH];
static uint8_t mems_frame[MEMS_FRAME_LENGTH];
static uint8_t star_frame[CAK_TLM_1_Info_Length];
static uint8_t photo_frame[249];
static uint8_t orbit_frame[89];
// 全局硬件状态
static HardwareStatus hw_status;
// 全局串口管理器
static map<string, unique_ptr<class SerialPort>> serial_ports;
// ==================================== 串口管理器类 ====================================
class SerialPort {
private:
int fd = -1;
string device_type; // 设备类型,如 "GNSS", "GYRO"等
string device_path;
atomic<bool> running{false};
thread read_thread;
mutex write_mutex;
// 协议解析缓冲区
uint8_t buffer[1024];
uint16_t buffer_index = 0;
public:
SerialPort(const string& type, const string& path)
: device_type(type), device_path(path) {}
~SerialPort() {
stop();
close();
}
bool open(int baudrate = 115200) {
// 打开串口设备
fd = ::open(device_path.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
spdlog::error("无法打开串口 {}: {}", device_path, strerror(errno));
return false;
}
// 配置串口参数
struct termios options;
if (tcgetattr(fd, &options) != 0) {
spdlog::error("获取串口属性失败: {}", strerror(errno));
::close(fd);
fd = -1;
return false;
}
// 设置波特率
speed_t baud;
switch (baudrate) {
case 9600: baud = B9600; break;
case 19200: baud = B19200; break;
case 38400: baud = B38400; break;
case 57600: baud = B57600; break;
case 115200: baud = B115200; break;
case 230400: baud = B230400; break;
case 460800: baud = B460800; break;
case 921600: baud = B921600; break;
default:
spdlog::error("不支持的波特率: {}", baudrate);
::close(fd);
fd = -1;
return false;
}
cfsetispeed(&options, baud);
cfsetospeed(&options, baud);
// 8位数据无校验1位停止位
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CRTSCTS; // 无硬件流控制
// 原始模式
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
// 设置读取超时
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10; // 1秒超时
if (tcsetattr(fd, TCSANOW, &options) != 0) {
spdlog::error("设置串口属性失败: {}", strerror(errno));
::close(fd);
fd = -1;
return false;
}
// 清除缓冲区
tcflush(fd, TCIOFLUSH);
spdlog::info("串口 {} ({}) 已打开,波特率: {}", device_type, device_path, baudrate);
return true;
}
void close() {
if (fd >= 0) {
::close(fd);
fd = -1;
spdlog::info("串口 {} 已关闭", device_type);
}
}
void start() {
if (fd < 0 || running) return;
running = true;
read_thread = thread(&SerialPort::read_loop, this);
spdlog::info("串口 {} 读取线程已启动", device_type);
}
void stop() {
running = false;
if (read_thread.joinable()) {
read_thread.join();
}
spdlog::info("串口 {} 读取线程已停止", device_type);
}
ssize_t write(const uint8_t* data, size_t len) {
lock_guard<mutex> lock(write_mutex);
if (fd < 0) {
spdlog::error("串口 {} 未打开,无法写入", device_type);
return -1;
}
ssize_t written = ::write(fd, data, len);
if (written < 0) {
spdlog::error("串口 {} 写入失败: {}", device_type, strerror(errno));
} else if (written != (ssize_t)len) {
spdlog::warn("串口 {} 部分写入: {}/{} 字节", device_type, written, len);
} else {
spdlog::debug("串口 {} 写入 {} 字节成功", device_type, len);
}
return written;
}
const string& get_type() const { return device_type; }
const string& get_path() const { return device_path; }
bool is_running() const { return running; }
private:
void read_loop() {
uint8_t read_buffer[1024];
spdlog::debug("串口 {} 读取线程开始", device_type);
while (running) {
// 使用poll检查是否有数据可读
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
int ret = poll(&pfd, 1, 100); // 100ms超时
if (ret < 0) {
spdlog::error("串口 {} poll失败: {}", device_type, strerror(errno));
break;
} else if (ret == 0) {
continue; // 超时,继续循环
}
if (pfd.revents & POLLIN) {
ssize_t n = read(fd, read_buffer, sizeof(read_buffer));
if (n > 0) {
process_serial_data(read_buffer, n);
} else if (n < 0 && errno != EAGAIN) {
spdlog::error("读取串口 {} 失败: {}", device_type, strerror(errno));
break;
}
}
}
spdlog::debug("串口 {} 读取线程结束", device_type);
}
void process_serial_data(const uint8_t* data, size_t len) {
spdlog::debug("串口 {} 接收到 {} 字节数据", device_type, len);
// 逐个字节处理数据
for (size_t i = 0; i < len; i++) {
uint8_t value = data[i];
// 根据设备类型调用相应的处理函数
if (device_type == "GNSS") {
process_gnss_data(value);
} else if (device_type == "GYRO") {
process_gyro_data(value);
} else if (device_type == "MEMS") {
process_mems_data(value);
} else if (device_type == "STAR1") {
process_star_1_data(value);
} else if (device_type == "STAR2") {
process_star_2_data(value);
} else if (device_type == "WHEEL1") {
process_wheel_1_data(value);
} else if (device_type == "WHEEL2") {
process_wheel_2_data(value);
} else if (device_type == "WHEEL3") {
process_wheel_3_data(value);
} else if (device_type == "OPTICAL") {
process_optical_data(value);
} else if (device_type == "VISION") {
process_vision_data(value);
} else {
spdlog::warn("未知设备类型: {}", device_type);
}
}
}
// ==================================== 协议解析函数 ====================================
void process_gnss_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
switch(rec_step) {
case 1:
if(data == 0xEB) {
buffer[rec_count++] = data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0x90) {
buffer[rec_count++] = data;
rec_step = 3;
} else {
spdlog::warn("GNSS帧头错误: 0xEB 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 3:
if(data == 0x09) {
buffer[rec_count++] = data;
rec_step = 4;
} else {
buffer[rec_count++] = data;
}
break;
case 4:
if(data == 0xD7) {
buffer[rec_count++] = data;
spdlog::info("GNSS数据接收完成, 长度: {}", rec_count);
// 处理GNSS指令并生成响应
handle_gnss_command();
} else {
spdlog::warn("GNSS帧尾错误: 0x{:02X}", data);
}
rec_step = 1;
rec_count = 0;
break;
default:
rec_step = 1;
rec_count = 0;
break;
}
}
void process_gyro_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
switch(rec_step) {
case 1:
if(data == 0x55) {
buffer[rec_count++] = data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0x68) {
buffer[rec_count++] = data;
spdlog::info("GYRO数据接收完成, 长度: {}", rec_count);
// 处理GYRO指令并生成响应
handle_gyro_command();
} else {
spdlog::warn("GYRO帧头错误: 0x55 0x{:02X}", data);
}
rec_step = 1;
rec_count = 0;
break;
default:
rec_step = 1;
rec_count = 0;
break;
}
}
void process_mems_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
switch(rec_step) {
case 1:
if(data == 0x55) {
buffer[rec_count++] = data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0x68) {
buffer[rec_count++] = data;
spdlog::info("MEMS数据接收完成, 长度: {}", rec_count);
// 处理MEMS指令并生成响应
handle_mems_command();
} else {
spdlog::warn("MEMS帧头错误: 0x55 0x{:02X}", data);
}
rec_step = 1;
rec_count = 0;
break;
default:
rec_step = 1;
rec_count = 0;
break;
}
}
void process_star_1_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
switch(rec_step) {
case 1:
if(data == 0x74) {
buffer[rec_count++] = data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0xA1) {
buffer[rec_count++] = data;
rec_step = 3;
} else {
spdlog::warn("STAR1帧头错误: 0x74 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 3:
buffer[rec_count++] = data;
if(rec_count == 5) {
if(buffer[4] == 0x15) {
spdlog::info("STAR-1数据接收完成, 长度: {}", rec_count);
// 处理STAR-1指令并生成响应
handle_star_1_command();
} else {
spdlog::warn("STAR-1帧尾错误: 0x{:02X}", buffer[4]);
}
rec_step = 1;
rec_count = 0;
}
break;
default:
rec_step = 1;
rec_count = 0;
break;
}
}
void process_star_2_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
switch(rec_step) {
case 1:
if(data == 0x74) {
buffer[rec_count++] = data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0xA1) {
buffer[rec_count++] = data;
rec_step = 3;
} else {
spdlog::warn("STAR2帧头错误: 0x74 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 3:
buffer[rec_count++] = data;
if(rec_count == 5) {
if(buffer[4] == 0x15) {
spdlog::info("STAR-2数据接收完成, 长度: {}", rec_count);
// 处理STAR-2指令并生成响应
handle_star_2_command();
} else {
spdlog::warn("STAR-2帧尾错误: 0x{:02X}", buffer[4]);
}
rec_step = 1;
rec_count = 0;
}
break;
default:
rec_step = 1;
rec_count = 0;
break;
}
}
void process_wheel_1_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
static uint8_t checksum = 0;
switch(rec_step) {
case 1:
if((data == 0x58) || (data == 0x59)) {
checksum = 0;
buffer[rec_count++] = data;
checksum += data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
checksum = 0;
}
break;
case 2:
buffer[rec_count++] = data;
if(rec_count == 11) {
if(checksum == data) {
spdlog::info("WHEEL-1数据接收完成, 长度: {}", rec_count);
// 处理WHEEL-1指令并生成响应
handle_wheel_1_command();
} else {
spdlog::warn("WHEEL-1校验和错误");
}
rec_step = 1;
rec_count = 0;
checksum = 0;
} else {
checksum += data;
}
break;
default:
rec_step = 1;
rec_count = 0;
checksum = 0;
break;
}
}
void process_wheel_2_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
static uint8_t checksum = 0;
switch(rec_step) {
case 1:
if((data == 0x58) || (data == 0x59)) {
checksum = 0;
buffer[rec_count++] = data;
checksum += data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
checksum = 0;
}
break;
case 2:
buffer[rec_count++] = data;
if(rec_count == 11) {
if(checksum == data) {
spdlog::info("WHEEL-2数据接收完成, 长度: {}", rec_count);
// 处理WHEEL-2指令并生成响应
handle_wheel_2_command();
} else {
spdlog::warn("WHEEL-2校验和错误");
}
rec_step = 1;
rec_count = 0;
checksum = 0;
} else {
checksum += data;
}
break;
default:
rec_step = 1;
rec_count = 0;
checksum = 0;
break;
}
}
void process_wheel_3_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
static uint8_t checksum = 0;
switch(rec_step) {
case 1:
if((data == 0x58) || (data == 0x59)) {
checksum = 0;
buffer[rec_count++] = data;
checksum += data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
checksum = 0;
}
break;
case 2:
buffer[rec_count++] = data;
if(rec_count == 11) {
if(checksum == data) {
spdlog::info("WHEEL-3数据接收完成, 长度: {}", rec_count);
// 处理WHEEL-3指令并生成响应
handle_wheel_3_command();
} else {
spdlog::warn("WHEEL-3校验和错误");
}
rec_step = 1;
rec_count = 0;
checksum = 0;
} else {
checksum += data;
}
break;
default:
rec_step = 1;
rec_count = 0;
checksum = 0;
break;
}
}
void process_optical_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
switch(rec_step) {
case 1:
if(data == 0xCD) {
buffer[rec_count++] = data;
rec_step = 2;
} else if(data == 0xEB) {
buffer[rec_count++] = data;
rec_step = 12;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0x90) {
buffer[rec_count++] = data;
rec_step = 3;
} else {
spdlog::warn("OPTICAL帧头错误: 0xCD 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 3:
buffer[rec_count++] = data;
if(rec_count == 5) {
if(buffer[4] == 0xFF) {
spdlog::info("OPTICAL数据接收完成, 长度: {}", rec_count);
// 处理OPTICAL指令并生成响应
handle_optical_command();
} else {
spdlog::warn("OPTICAL帧尾错误: 0x{:02X}", buffer[4]);
}
rec_step = 1;
rec_count = 0;
}
break;
case 12:
if(data == 0x90) {
buffer[rec_count++] = data;
rec_step = 13;
} else {
spdlog::warn("OPTICAL扩展帧头错误: 0xEB 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 13:
buffer[rec_count++] = data;
if(rec_count == 8) {
uint8_t checksum = 0;
for(int kc = 0; kc < rec_count - 1; kc++) {
checksum += buffer[kc];
}
if(buffer[7] == checksum) {
spdlog::info("OPTICAL带参指令接收完成, 长度: {}", rec_count);
// 处理OPTICAL带参指令
handle_optical_command();
} else {
spdlog::warn("OPTICAL带参指令校验错误");
}
rec_step = 1;
rec_count = 0;
}
break;
default:
rec_step = 1;
rec_count = 0;
break;
}
}
void process_vision_data(uint8_t data) {
static uint8_t rec_step = 1;
static uint16_t rec_count = 0;
static uint16_t frame_len = 0;
switch(rec_step) {
case 1:
if(data == 0xEB) {
buffer[rec_count++] = data;
rec_step = 2;
} else {
rec_step = 1;
rec_count = 0;
}
break;
case 2:
if(data == 0x90) {
buffer[rec_count++] = data;
rec_step = 3;
} else {
spdlog::warn("VISION帧头错误: 0xEB 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 3:
if((data == 0x1E) || (data == 0x0F)) {
buffer[rec_count++] = data;
rec_step = 4;
} else {
spdlog::warn("VISION指令类型错误: 0x{:02X}", data);
rec_step = 1;
rec_count = 0;
}
break;
case 4:
buffer[rec_count++] = data;
rec_step = 5;
break;
case 5:
buffer[rec_count++] = data;
frame_len = (buffer[3] * 256) + buffer[4];
rec_step = 6;
break;
case 6:
buffer[rec_count++] = data;
if(rec_count == (frame_len + 6)) {
uint8_t checksum = 0;
for(int kc = 2; kc < rec_count - 1; kc++) {
checksum += buffer[kc];
}
if(buffer[rec_count - 1] == checksum) {
spdlog::info("VISION数据接收完成, 长度: {}", rec_count);
// 处理VISION指令并生成响应
handle_vision_command();
} else {
spdlog::warn("VISION校验和错误");
}
rec_step = 1;
rec_count = 0;
frame_len = 0;
}
break;
default:
rec_step = 1;
rec_count = 0;
frame_len = 0;
break;
}
}
// ==================================== 命令处理函数 ====================================
void handle_gnss_command() {
if (!hw_status.gnss_onoff) {
spdlog::info("GNSS功能已关闭不生成响应");
return;
}
// 直接调用现有的GNSS数据生成函数
generate_gnss_frame(gnss_frame, ChaRVECI, mjd, Epoch2017);
// 发送响应
write(gnss_frame, GPS_Hk_FRAME_LENGTH);
spdlog::info("已发送GNSS响应数据长度: {}", GPS_Hk_FRAME_LENGTH);
}
void handle_gyro_command() {
if (!hw_status.gyro_onoff) {
spdlog::info("GYRO功能已关闭不生成响应");
return;
}
// 直接调用现有的GYRO数据生成函数
generate_gyro_frame(gyro_frame, AttiVelECI);
// 发送响应
write(gyro_frame, GYRO_FRAME_LENGTH);
spdlog::info("已发送GYRO响应数据长度: {}", GYRO_FRAME_LENGTH);
}
void handle_mems_command() {
if (!hw_status.mems_onoff) {
spdlog::info("MEMS功能已关闭不生成响应");
return;
}
// 直接调用现有的MEMS数据生成函数
generate_mems_frame(mems_frame, AttiVelECI);
// 发送响应
write(mems_frame, MEMS_FRAME_LENGTH);
spdlog::info("已发送MEMS响应数据长度: {}", MEMS_FRAME_LENGTH);
}
void handle_star_1_command() {
if (!hw_status.star_onoff) {
spdlog::info("STAR-1功能已关闭不生成响应");
return;
}
// 获取四元数
get_orbit_Q(QuatECI);
// 直接调用现有的STAR-1数据生成函数
generate_star_1_frame(star_frame, QuatECI, AttiVelECI);
// 发送响应
write(star_frame, CAK_TLM_1_Info_Length);
spdlog::info("已发送STAR-1响应数据长度: {}", CAK_TLM_1_Info_Length);
}
void handle_star_2_command() {
if (!hw_status.star_onoff) {
spdlog::info("STAR-2功能已关闭不生成响应");
return;
}
// 获取四元数
get_orbit_Q(QuatECI);
// 直接调用现有的STAR-2数据生成函数
generate_star_2_frame(star_frame, QuatECI, AttiVelECI);
// 发送响应
write(star_frame, CAK_TLM_1_Info_Length);
spdlog::info("已发送STAR-2响应数据长度: {}", CAK_TLM_1_Info_Length);
}
void handle_wheel_1_command() {
if (!hw_status.wheel_onoff) {
spdlog::info("WHEEL-1功能已关闭不生成响应");
return;
}
// 解析转速命令从buffer中解析
if (buffer_index >= 5) {
hw_status.CmdWheel[0] = cal_message_para(buffer[1], buffer[2], buffer[3], buffer[4], WHEEL_EXP);
spdlog::info("WHEEL-1转速命令: {:.2f} rpm", hw_status.CmdWheel[0]);
// 更新动量轮仿真数据
sensor_WheelMeas(hw_status.WheelTorqueBody, hw_status.WheelAM, hw_status.CmdWheel);
}
// 直接调用现有的WHEEL数据生成函数
generate_wheel_frame(wheel_frame, hw_status.CmdWheel[0]);
// 发送响应
write(wheel_frame, WHEEL_FRAME_LENGTH);
spdlog::info("已发送WHEEL-1响应数据长度: {}", WHEEL_FRAME_LENGTH);
}
void handle_wheel_2_command() {
if (!hw_status.wheel_onoff) {
spdlog::info("WHEEL-2功能已关闭不生成响应");
return;
}
// 解析转速命令
if (buffer_index >= 5) {
hw_status.CmdWheel[1] = cal_message_para(buffer[1], buffer[2], buffer[3], buffer[4], WHEEL_EXP);
spdlog::info("WHEEL-2转速命令: {:.2f} rpm", hw_status.CmdWheel[1]);
// 更新动量轮仿真数据
sensor_WheelMeas(hw_status.WheelTorqueBody, hw_status.WheelAM, hw_status.CmdWheel);
}
// 直接调用现有的WHEEL数据生成函数
generate_wheel_frame(wheel_frame, hw_status.CmdWheel[1]);
// 发送响应
write(wheel_frame, WHEEL_FRAME_LENGTH);
spdlog::info("已发送WHEEL-2响应数据长度: {}", WHEEL_FRAME_LENGTH);
}
void handle_wheel_3_command() {
if (!hw_status.wheel_onoff) {
spdlog::info("WHEEL-3功能已关闭不生成响应");
return;
}
// 解析转速命令
if (buffer_index >= 5) {
hw_status.CmdWheel[2] = cal_message_para(buffer[1], buffer[2], buffer[3], buffer[4], WHEEL_EXP);
spdlog::info("WHEEL-3转速命令: {:.2f} rpm", hw_status.CmdWheel[2]);
// 更新动量轮仿真数据
sensor_WheelMeas(hw_status.WheelTorqueBody, hw_status.WheelAM, hw_status.CmdWheel);
}
// 直接调用现有的WHEEL数据生成函数
generate_wheel_frame(wheel_frame, hw_status.CmdWheel[2]);
// 发送响应
write(wheel_frame, WHEEL_FRAME_LENGTH);
spdlog::info("已发送WHEEL-3响应数据长度: {}", WHEEL_FRAME_LENGTH);
}
void handle_optical_command() {
if (!hw_status.optical_onoff) {
spdlog::info("OPTICAL功能已关闭不生成响应");
return;
}
// 根据指令类型处理
if (buffer_index >= 4) {
if (buffer[2] == 0x06 && buffer[3] == 0x00) {
// 遥测指令 - 直接调用现有的光电数据生成函数
generate_xgd_frame(xgd_frame, TarRVECI, ChaRVECI, MtxECI2VVLH,
MtxVVLH2Body, LOS_Remote, EulerVVLH, R_Plane, TargetFLAG);
write(xgd_frame, OPTIC_FRAME_LENGTH);
spdlog::info("已发送OPTICAL遥测数据长度: {}", OPTIC_FRAME_LENGTH);
} else if ((buffer[2] == 0x07 && buffer[3] == 0x01) ||
(buffer[2] == 0x08 && buffer[3] == 0x01)) {
// 图像指令 - 直接调用现有的图像生成函数
generate_photo_frame(photo_frame);
write(photo_frame, 249);
spdlog::info("已发送OPTICAL图像数据长度: 249");
} else {
spdlog::warn("未知的OPTICAL指令: 0x{:02X} 0x{:02X}", buffer[2], buffer[3]);
}
}
}
void handle_vision_command() {
if (buffer_index >= 3 && buffer[2] == 0x0F) {
// 遥测指令 - 直接调用现有的TX2数据生成函数
generate_tx2_frame(tx2_frame, LOS_Remote, R_Plane, TarRVECI, ChaRVECI,
MtxVVLH2Body, MtxECI2VVLH, TargetFLAG);
write(tx2_frame, VISION_Info_Length);
spdlog::info("已发送VISION遥测数据长度: {}", VISION_Info_Length);
} else {
spdlog::warn("未知的VISION指令类型: 0x{:02X}", buffer[2]);
}
}
};
// ==================================== 主初始化函数 ====================================
void initialize_simulation_system() {
cout << "=== 星载硬件仿真系统初始化 ===" << endl;
cout << "初始化Linux串口仿真系统..." << endl;
// 初始化轨道信息
orbit_info_initz("./settings/setting.json");
uint8_t dummy_orbit_frame[89] = {0};
set_orbit_info(dummy_orbit_frame, AttiVelECI, EulerVVLH, MtxVVLH2Body, MtxECI2VVLH);
spdlog::info("初始化后角速度: [{:.6f}, {:.6f}, {:.6f}] 弧度/秒",
AttiVelECI[0], AttiVelECI[1], AttiVelECI[2]);
spdlog::info("转换为度/秒: [{:.6f}, {:.6f}, {:.6f}] 度/秒",
AttiVelECI[0] * 180.0 / M_PI,
AttiVelECI[1] * 180.0 / M_PI,
AttiVelECI[2] * 180.0 / M_PI);
// 获取四元数
get_orbit_Q(QuatECI);
// 串口设备映射配置
cout << "1. 配置串口设备..." << endl;
map<string, string> port_config = {
{"GNSS", "/dev/tnt0"}, // GNSS接收机
{"GYRO", "/dev/tnt2"}, // 陀螺仪
{"MEMS", "/dev/tnt4"}, // MEMS加速度计
{"STAR1", "/dev/tnt6"}, // 星敏感器1
{"STAR2", "/dev/tnt8"}, // 星敏感器2
{"WHEEL1", "/dev/tnt10"}, // 动量轮1
{"WHEEL2", "/dev/tnt12"}, // 动量轮2
{"WHEEL3", "/dev/tnt14"}, // 动量轮3
{"OPTICAL", "/dev/tnt16"}, // 小光电
{"VISION", "/dev/tnt18"} // TX2视觉
};
// 打开所有串口设备
cout << "2. 开始打开串口设备..." << endl;
int opened_ports = 0;
for (const auto& config : port_config) {
cout << " 尝试打开: " << config.first << " -> " << config.second << "... ";
cout.flush();
auto port = make_unique<SerialPort>(config.first, config.second);
if (port->open(115200)) {
port->start();
serial_ports[config.first] = move(port);
opened_ports++;
cout << "✅ 成功" << endl;
} else {
cout << "❌ 失败" << endl;
}
}
cout << "===============================================" << endl;
cout << "✅ 星载硬件仿真系统初始化完成" << endl;
cout << " 成功打开 " << opened_ports << "/" << port_config.size() << " 个串口设备" << endl;
cout << " 系统已就绪,开始监听串口指令..." << endl;
cout << "=== 初始化完成 ===" << endl;
}
// ==================================== 清理函数 ====================================
void cleanup_simulation_system() {
spdlog::info("清理仿真系统资源...");
for (auto& pair : serial_ports) {
spdlog::info("关闭串口: {}", pair.first);
pair.second->stop();
pair.second->close();
}
serial_ports.clear();
spdlog::info("仿真系统资源清理完成");
}
// ==================================== 主函数 ====================================
int main(int argc, char** argv) {
// 初始化日志系统
spdlog_initz("./settings/setting.json");
cout << "**************************************************" << endl;
cout << "* 星载硬件仿真系统 - 单程序版本 *" << endl;
cout << "* *" << endl;
cout << "* 功能:监听串口 -> 解析指令 -> 调用现有仿真函数*" << endl;
cout << "* *" << endl;
cout << "**************************************************" << endl;
cout << endl;
// 初始化仿真系统
initialize_simulation_system();
// 注册信号处理
std::signal(SIGINT, [](int) {
cout << "\n收到中断信号,正在关闭系统..." << endl;
cleanup_simulation_system();
exit(0);
});
std::signal(SIGTERM, [](int) {
cout << "\n收到终止信号,正在关闭系统..." << endl;
cleanup_simulation_system();
exit(0);
});
// 主循环
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}