当前位置: 首页 > news >正文

舰船摇摆下的坐标变换技术

为了根据目标的经纬高(BLH)和转台自身的经纬高(BLH)以及本舰的姿态(横摇、纵摇、艏摇)求解转台的指令角(方位角和高低角),并通过C++程序实现,我们需要完成以下步骤:

  1. 将目标和转台的BLH坐标转换为地心地固坐标系(ECEF)坐标。

  2. 计算目标相对于转台的ECEF向量。

  3. 将该向量转换为东北地坐标系(NED)中的向量。

  4. 使用本舰姿态将NED向量转换到舰船坐标系。

  5. 在舰船坐标系中计算方位角和高低角。

以下是完整的C++代码实现,包括必要的数学计算和坐标变换。

#include <iostream>
#include <cmath>
#include <vector>// 定义WGS84椭球参数
const double WGS84_A = 6378137.0; // 半长轴
const double WGS84_F = 1.0 / 298.257223563; // 扁率
const double WGS84_E2 = 2 * WGS84_F - WGS84_F * WGS84_F; // 第一偏心率平方// 结构体存储BLH坐标
struct BLH {double lat; // 纬度,弧度double lon; // 经度,弧度double height; // 高度,米
};// 结构体存储姿态角(横摇、纵摇、艏摇),弧度
struct Attitude {double roll; // 横摇 φdouble pitch; // 纵摇 θdouble yaw; // 艏摇 ψ
};// 将BLH转换为ECEF坐标
std::vector<double> blhToEcef(const BLH& blh) {double sinLat = sin(blh.lat);double cosLat = cos(blh.lat);double sinLon = sin(blh.lon);double cosLon = cos(blh.lon);double N = WGS84_A / sqrt(1 - WGS84_E2 * sinLat * sinLat);double x = (N + blh.height) * cosLat * cosLon;double y = (N + blh.height) * cosLat * sinLon;double z = (N * (1 - WGS84_E2) + blh.height) * sinLat;return {x, y, z};
}// 计算从ECEF到NED的旋转矩阵
std::vector<std::vector<double>> ecefToNedMatrix(const BLH& blh) {double sinLat = sin(blh.lat);double cosLat = cos(blh.lat);double sinLon = sin(blh.lon);double cosLon = cos(blh.lon);std::vector<std::vector<double>> R = {{-sinLat * cosLon, -sinLat * sinLon, cosLat},{-sinLon, cosLon, 0},{-cosLat * cosLon, -cosLat * sinLon, -sinLat}};return R;
}// 计算从NED到舰船坐标系的旋转矩阵(基于姿态)
std::vector<std::vector<double>> nedToBodyMatrix(const Attitude& att) {double sinRoll = sin(att.roll);double cosRoll = cos(att.roll);double sinPitch = sin(att.pitch);double cosPitch = cos(att.pitch);double sinYaw = sin(att.yaw);double cosYaw = cos(att.yaw);// 旋转矩阵:R_body_ned = R_x(roll) * R_y(pitch) * R_z(yaw)std::vector<std::vector<double>> R = {{cosPitch * cosYaw, cosPitch * sinYaw, -sinPitch},{sinRoll * sinPitch * cosYaw - cosRoll * sinYaw, sinRoll * sinPitch * sinYaw + cosRoll * cosYaw, sinRoll * cosPitch},{cosRoll * sinPitch * cosYaw + sinRoll * sinYaw, cosRoll * sinPitch * sinYaw - sinRoll * cosYaw, cosRoll * cosPitch}};return R;
}// 矩阵乘以向量
std::vector<double> matrixMultiply(const std::vector<std::vector<double>>& M, const std::vector<double>& v) {std::vector<double> result(3, 0.0);for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {result[i] += M[i][j] * v[j];}}return result;
}// 计算指令角:方位角和高低角(弧度)
void computePointingAngles(const BLH& targetBLH, const BLH& platformBLH, const Attitude& platformAtt, double& az, double& el) {// 1. 将目标和平台BLH转换为ECEFstd::vector<double> targetECEF = blhToEcef(targetBLH);std::vector<double> platformECEF = blhToEcef(platformBLH);// 2. 计算相对ECEF向量std::vector<double> deltaECEF = {targetECEF[0] - platformECEF[0],targetECEF[1] - platformECEF[1],targetECEF[2] - platformECEF[2]};// 3. 计算ECEF到NED的旋转矩阵std::vector<std::vector<double>> R_ecef2ned = ecefToNedMatrix(platformBLH);// 将相对ECEF向量转换到NED坐标系std::vector<double> deltaNED = matrixMultiply(R_ecef2ned, deltaECEF);// 4. 计算NED到舰船坐标系的旋转矩阵std::vector<std::vector<double>> R_ned2body = nedToBodyMatrix(platformAtt);// 将NED向量转换到舰船坐标系std::vector<double> bodyVec = matrixMultiply(R_ned2body, deltaNED);double x_b = bodyVec[0];double y_b = bodyVec[1];double z_b = bodyVec[2];// 5. 计算方位角和高低角az = atan2(y_b, x_b); // 方位角:atan2(y_b, x_b)double r = sqrt(x_b * x_b + y_b * y_b);el = atan2(-z_b, r); // 高低角:因为舰船坐标系z向下,所以用-z_b
}int main() {// 示例数据BLH targetBLH;targetBLH.lat = 0.5; // 弧度targetBLH.lon = 0.5; // 弧度targetBLH.height = 1000.0; // 米BLH platformBLH;platformBLH.lat = 0.5; // 弧度platformBLH.lon = 0.5; // 弧度platformBLH.height = 0.0; // 米Attitude platformAtt;platformAtt.roll = 0.1; // 弧度platformAtt.pitch = 0.05; // 弧度platformAtt.yaw = 1.0; // 弧度double az, el;computePointingAngles(targetBLH, platformBLH, platformAtt, az, el);// 输出结果(弧度)std::cout << "Azimuth (rad): " << az << std::endl;std::cout << "Elevation (rad): " << el << std::endl;// 转换为度数输出std::cout << "Azimuth (deg): " << az * 180.0 / M_PI << std::endl;std::cout << "Elevation (deg): " << el * 180.0 / M_PI << std::endl;return 0;
}

代码说明:

  1. 常量和结构体定义:定义了WGS84椭球参数,以及存储BLH和姿态的结构体。

  2. blhToEcef函数:将BLH坐标转换为ECEF坐标。

  3. ecefToNedMatrix函数:计算从ECEF到NED坐标系的旋转矩阵。

  4. nedToBodyMatrix函数:根据姿态角计算从NED到舰船坐标系的旋转矩阵。

  5. matrixMultiply函数:实现3x3矩阵与3x1向量的乘法。

  6. computePointingAngles函数:主计算函数,完成所有坐标变换并计算指令角。

  7. main函数:示例用法,计算并输出方位角和高低角(弧度和度数)。

注意事项:

  • 输入角度单位为弧度,输出指令角也为弧度。

  • 舰船坐标系的定义:x轴向前(舰首),y轴向右(右舷),z轴向下。因此高低角计算时使用-z_b以得到正确的仰角。

  • 实际应用中,可能需要考虑姿态角的顺序和符号,这里采用常见的Z-Y-X顺序(艏摇、纵摇、横摇)。

  • 代码假设目标和平台的BLH坐标以及姿态角是已知的。

此代码提供了一个完整的框架,可以根据实际需求进行调整和优化。

开启新对话

http://www.dtcms.com/a/350711.html

相关文章:

  • coze工作流200+源码,涵盖AI文案生成、图像处理、视频生成、自动化脚本等多个领域
  • Metabase 部署与实践:从测试环境到生产环境的完整指南
  • celery prefetch-multiplier
  • 【人工智能】人工智能在企业中的应用
  • 理解Vuex的辅助函数,分析mapState、mapGetters、mapMutations和mapActions各个应用场景
  • [信号与系统个人笔记]第二章 连续时间信号与系统的时域分析
  • 【MySQL】MySQL介绍及安装
  • 查看mariadb服务是否启动
  • 2025 BrunnerCTF remobile 部分wp
  • 编译型语言(C/C++):从源码到.exe 的完整链路
  • 语音识别:概念与接口
  • LeetCode 面试经典 150_双指针_验证回文串(25_125_C++_简单)(双指针)
  • 【JVM内存结构系列】六、“特殊区域”:直接内存、栈上分配与TLAB
  • JavaScript 对象 Array对象 Math对象
  • Spring Boot 结合 Jasypt 实现敏感信息加密(含 Nacos 配置关联思路)
  • 计算机网络:HTTP、抓包、TCP和UDP报文及重要概念
  • 简述Myisam和Innodb的区别?
  • 面试题:reids缓存和数据库的区别
  • Android FrameWork - Zygote 启动流程分析
  • 【0419】Postgres内核 buffer pool 所需共享内存(shared memory)大小
  • 物流架构实践:ZKmall开源商城物流接口对接与状态同步
  • Pytorch框架的训练测试以及优化
  • 使用JDK11标准 实现 图数据结构的增删查改遍历 可视化程序
  • Spring Cloud Alibaba
  • 机器学习三大核心思想:数据驱动、自动优化与泛化能力
  • 搭建python自动化测试环境
  • kmeans
  • 【Kotlin】Kotlin 常用注解详解与实战
  • 2025山东国际大健康产业博览会外贸优品中华行活动打造内外贸一体化高效平台
  • 瑞惯科技双轴倾角传感器厂家指南