LeGO LOAM坐标系问题的自我思考

LeGO LOAM坐标系问题的自我思考

  • 总体思考流程
  • IMU坐标系
  • LeGO LOAM代码分析
    • 代码
  • 对于IMU输出测量值的integration积分过程
  • 欧拉角的旋转矩阵
    • VeloToStartIMU()函数
    • TransformToStartIMU(PointType *p)

总体思考流程

第一页
请添加图片描述第二页
请添加图片描述第三页
请添加图片描述

IMU坐标系

在LeGO LOAM中IMU坐标系的形式采用前(x)-左(y)-上(z)的形式,IMU坐标系同时可以表示为载体坐标系(body frame)世界坐标系表示的形式采用左(x)-上(y)-前(z)的形式,世界坐标系也可以称为world系世界坐标系作为一种固定的坐标系,而IMU坐标系作为一种非固定坐标系

下图展示为两种坐标系的表示形式:
(下图展示的坐标系为IMU坐标系)
在这里插入图片描述
(下图展示的坐标系为世界坐标系)
在这里插入图片描述
坐标系在实体汽车上的表示:
在这里插入图片描述

LeGO LOAM代码分析

代码

void imuHandler(const sensor_msgs::Imu::ConstPtr& imuIn){double roll, pitch, yaw;tf::Quaternion orientation;tf::quaternionMsgToTF(imuIn->orientation, orientation);tf::Matrix3x3(orientation).getRPY(roll, pitch, yaw);float accX = imuIn->linear_acceleration.y - sin(roll) * cos(pitch) * 9.81;float accY = imuIn->linear_acceleration.z - cos(roll) * cos(pitch) * 9.81;float accZ = imuIn->linear_acceleration.x + sin(pitch) * 9.81;imuPointerLast = (imuPointerLast + 1) % imuQueLength;imuTime[imuPointerLast] = imuIn->header.stamp.toSec();imuRoll[imuPointerLast] = roll;imuPitch[imuPointerLast] = pitch;imuYaw[imuPointerLast] = yaw;imuAccX[imuPointerLast] = accX;imuAccY[imuPointerLast] = accY;imuAccZ[imuPointerLast] = accZ;imuAngularVeloX[imuPointerLast] = imuIn->angular_velocity.x;imuAngularVeloY[imuPointerLast] = imuIn->angular_velocity.y;imuAngularVeloZ[imuPointerLast] = imuIn->angular_velocity.z;AccumulateIMUShiftAndRotation();}

上述代码为消除IMU测量的加速度数据受到重力加速度的影响(重力加速度存在于world坐标系)

  1. 因为IMU坐标系与world坐标系是不对齐的,所以,下面这三行代码的用途如下:
#输出的为在IMU与world坐标系一致朝向的IMU坐标系下的新IMU坐标系下的加速度 测量数据值float accX = imuIn->linear_acceleration.y - sin(roll) * cos(pitch) * 9.81;float accY = imuIn->linear_acceleration.z - cos(roll) * cos(pitch) * 9.81;float accZ = imuIn->linear_acceleration.x + sin(pitch) * 9.81;

将重力加速度转到IMU坐标系,然后执行消除重力的影响:涉及的公式如下
在这里插入图片描述在这里插入图片描述在这里插入图片描述
同时因为IMU坐标系与world坐标系不对齐,所以第二部将X->y,Y->z,Z->x实则是考虑一个新的IMU坐标系,使得这个新的IMU坐标与world坐标系能够在朝向上一致!!!(但是需要区分的是此时新的IMU坐标系和world坐标系只是朝向一致,但是他们并不是同一个坐标系!!!)
在这里插入图片描述

  1. 但是对于imu坐标系表示为前x->左y->上z新的IMU坐标系(IMU’)表示为左x->上y->前z,所以 最终得到的accX,accY,accZ分别经过imu到IMU’的坐标系的变换,(所以需要经历的变换为如下图所示:)
    在这里插入图片描述

对于IMU输出测量值的integration积分过程

因为accX,accY,accZ对应的都是IMU表示的新的坐标系(IMU’)下的测量数据值,因为IMU到world坐标系下的旋转满足yaw-pitch-roll旋转,同时是内旋,满足右乘,所以最终满足的公式为:
在这里插入图片描述

// rollfloat x1 = cos(roll) * accX - sin(roll) * accY;float y1 = sin(roll) * accX + cos(roll) * accY;float z1 = accZ;//z

在这里插入图片描述

// pitchfloat x2 = x1;//xfloat y2 = cos(pitch) * y1 - sin(pitch) * z1;float z2 = sin(pitch) * y1 + cos(pitch) * z1;

在这里插入图片描述

//yawaccX = cos(yaw) * x2 + sin(yaw) * z2;accY = y2;//yaccZ = -sin(yaw) * x2 + cos(yaw) * z2;

在这里插入图片描述
IMU坐标系转为机器人坐标系(左X(pitch)->上Y(yaw)->前Z(roll)),需要按照转换后的坐标系进行欧拉角的旋转yaw->pitch->roll的内旋右乘->表示为先✖roll(Z)->再✖pitch(x)->再✖yaw(Y)

    void AccumulateIMUShiftAndRotation(){float roll = imuRoll[imuPointerLast];float pitch = imuPitch[imuPointerLast];float yaw = imuYaw[imuPointerLast];float accX = imuAccX[imuPointerLast];float accY = imuAccY[imuPointerLast];float accZ = imuAccZ[imuPointerLast];
//将新的坐标系IMU'数据通过YAW->PITCH->ROLL转到world坐标系
// roll zfloat x1 = cos(roll) * accX - sin(roll) * accY;float y1 = sin(roll) * accX + cos(roll) * accY;float z1 = accZ;//z
//pitch xfloat x2 = x1;//xfloat y2 = cos(pitch) * y1 - sin(pitch) * z1;float z2 = sin(pitch) * y1 + cos(pitch) * z1;
//yaw yaccX = cos(yaw) * x2 + sin(yaw) * z2;accY = y2;//yaccZ = -sin(yaw) * x2 + cos(yaw) * z2;int imuPointerBack = (imuPointerLast + imuQueLength - 1) % imuQueLength;double timeDiff = imuTime[imuPointerLast] - imuTime[imuPointerBack];if (timeDiff < scanPeriod) {
// 最终得到的 Shift | Velo | AngularRotation均表示为world坐标系下的数值imuShiftX[imuPointerLast] = imuShiftX[imuPointerBack] + imuVeloX[imuPointerBack] * timeDiff + accX * timeDiff * timeDiff / 2;imuShiftY[imuPointerLast] = imuShiftY[imuPointerBack] + imuVeloY[imuPointerBack] * timeDiff + accY * timeDiff * timeDiff / 2;imuShiftZ[imuPointerLast] = imuShiftZ[imuPointerBack] + imuVeloZ[imuPointerBack] * timeDiff + accZ * timeDiff * timeDiff / 2;imuVeloX[imuPointerLast] = imuVeloX[imuPointerBack] + accX * timeDiff;imuVeloY[imuPointerLast] = imuVeloY[imuPointerBack] + accY * timeDiff;imuVeloZ[imuPointerLast] = imuVeloZ[imuPointerBack] + accZ * timeDiff;imuAngularRotationX[imuPointerLast] = imuAngularRotationX[imuPointerBack] + imuAngularVeloX[imuPointerBack] * timeDiff;imuAngularRotationY[imuPointerLast] = imuAngularRotationY[imuPointerBack] + imuAngularVeloY[imuPointerBack] * timeDiff;imuAngularRotationZ[imuPointerLast] = imuAngularRotationZ[imuPointerBack] + imuAngularVeloZ[imuPointerBack] * timeDiff;}}

其最终得到的速度,偏移以及旋转的积分数据值表示的为在world坐标系下的数据

欧拉角的旋转矩阵

在adjustDistortion对点云数据执行运动去畸变的过程是这样的,首先将lidar点云同样与IMU数据统一的跟world坐标系同指向的新的lidar’坐标系(用来与world坐标系的朝向对齐):执行如下代码的变换:

point.x = segmentedCloud->points[i].y;point.y = segmentedCloud->points[i].z;point.z = segmentedCloud->points[i].x;

然后,找到针对此刻点云对应的IMU数据信息,如果是第一帧,则不需要旋转到IMU对应的初始时刻 但是对于在scanperiod的时间间隔内,lidar360度旋转,非第一帧对应的初始时刻的IMU数据,则需要转换到初始时刻的IMU数据坐标系下也就是涉及的两个函数VeloToStartIMU()函数和TransformToStartIMU(point)函数

void adjustDistortion(){bool halfPassed = false;int cloudSize = segmentedCloud->points.size();PointType point;for (int i = 0; i < cloudSize; i++) {point.x = segmentedCloud->points[i].y;point.y = segmentedCloud->points[i].z;point.z = segmentedCloud->points[i].x;float ori = -atan2(point.x, point.z);if (!halfPassed) {if (ori < segInfo.startOrientation - M_PI / 2)ori += 2 * M_PI;else if (ori > segInfo.startOrientation + M_PI * 3 / 2)ori -= 2 * M_PI;if (ori - segInfo.startOrientation > M_PI)halfPassed = true;}else {ori += 2 * M_PI;if (ori < segInfo.endOrientation - M_PI * 3 / 2)ori += 2 * M_PI;else if (ori > segInfo.endOrientation + M_PI / 2)ori -= 2 * M_PI;}float relTime = (ori - segInfo.startOrientation) / segInfo.orientationDiff;point.intensity = int(segmentedCloud->points[i].intensity) + scanPeriod * relTime;if (imuPointerLast >= 0) {//have imu datafloat pointTime = relTime * scanPeriod;imuPointerFront = imuPointerLastIteration;while (imuPointerFront != imuPointerLast) {if (timeScanCur + pointTime < imuTime[imuPointerFront]) {break;}imuPointerFront = (imuPointerFront + 1) % imuQueLength;}//find the imuPointerFront (imu time ) > current scan timeif (timeScanCur + pointTime > imuTime[imuPointerFront]) {//no imu dataimuRollCur = imuRoll[imuPointerFront];//imu data coverageimuPitchCur = imuPitch[imuPointerFront];imuYawCur = imuYaw[imuPointerFront];imuVeloXCur = imuVeloX[imuPointerFront];imuVeloYCur = imuVeloY[imuPointerFront];imuVeloZCur = imuVeloZ[imuPointerFront];imuShiftXCur = imuShiftX[imuPointerFront];imuShiftYCur = imuShiftY[imuPointerFront];imuShiftZCur = imuShiftZ[imuPointerFront];   } else {int imuPointerBack = (imuPointerFront + imuQueLength - 1) % imuQueLength;//0-1 % imuQueLength xfloat ratioFront = (timeScanCur + pointTime - imuTime[imuPointerBack]) / (imuTime[imuPointerFront] - imuTime[imuPointerBack]);float ratioBack = (imuTime[imuPointerFront] - timeScanCur - pointTime) / (imuTime[imuPointerFront] - imuTime[imuPointerBack]);imuRollCur = imuRoll[imuPointerFront] * ratioFront + imuRoll[imuPointerBack] * ratioBack;imuPitchCur = imuPitch[imuPointerFront] * ratioFront + imuPitch[imuPointerBack] * ratioBack;if (imuYaw[imuPointerFront] - imuYaw[imuPointerBack] > M_PI) {imuYawCur = imuYaw[imuPointerFront] * ratioFront + (imuYaw[imuPointerBack] + 2 * M_PI) * ratioBack;} else if (imuYaw[imuPointerFront] - imuYaw[imuPointerBack] < -M_PI) {imuYawCur = imuYaw[imuPointerFront] * ratioFront + (imuYaw[imuPointerBack] - 2 * M_PI) * ratioBack;} else {imuYawCur = imuYaw[imuPointerFront] * ratioFront + imuYaw[imuPointerBack] * ratioBack;}imuVeloXCur = imuVeloX[imuPointerFront] * ratioFront + imuVeloX[imuPointerBack] * ratioBack;imuVeloYCur = imuVeloY[imuPointerFront] * ratioFront + imuVeloY[imuPointerBack] * ratioBack;imuVeloZCur = imuVeloZ[imuPointerFront] * ratioFront + imuVeloZ[imuPointerBack] * ratioBack;imuShiftXCur = imuShiftX[imuPointerFront] * ratioFront + imuShiftX[imuPointerBack] * ratioBack;imuShiftYCur = imuShiftY[imuPointerFront] * ratioFront + imuShiftY[imuPointerBack] * ratioBack;imuShiftZCur = imuShiftZ[imuPointerFront] * ratioFront + imuShiftZ[imuPointerBack] * ratioBack;}if (i == 0) {//first point cloud initializationimuRollStart = imuRollCur;imuPitchStart = imuPitchCur;imuYawStart = imuYawCur;imuVeloXStart = imuVeloXCur;imuVeloYStart = imuVeloYCur;imuVeloZStart = imuVeloZCur;imuShiftXStart = imuShiftXCur;imuShiftYStart = imuShiftYCur;imuShiftZStart = imuShiftZCur;if (timeScanCur + pointTime > imuTime[imuPointerFront]) {imuAngularRotationXCur = imuAngularRotationX[imuPointerFront];imuAngularRotationYCur = imuAngularRotationY[imuPointerFront];imuAngularRotationZCur = imuAngularRotationZ[imuPointerFront];}else{int imuPointerBack = (imuPointerFront + imuQueLength - 1) % imuQueLength;float ratioFront = (timeScanCur + pointTime - imuTime[imuPointerBack]) / (imuTime[imuPointerFront] - imuTime[imuPointerBack]);float ratioBack = (imuTime[imuPointerFront] - timeScanCur - pointTime) / (imuTime[imuPointerFront] - imuTime[imuPointerBack]);imuAngularRotationXCur = imuAngularRotationX[imuPointerFront] * ratioFront + imuAngularRotationX[imuPointerBack] * ratioBack;imuAngularRotationYCur = imuAngularRotationY[imuPointerFront] * ratioFront + imuAngularRotationY[imuPointerBack] * ratioBack;imuAngularRotationZCur = imuAngularRotationZ[imuPointerFront] * ratioFront + imuAngularRotationZ[imuPointerBack] * ratioBack;}imuAngularFromStartX = imuAngularRotationXCur - imuAngularRotationXLast;imuAngularFromStartY = imuAngularRotationYCur - imuAngularRotationYLast;imuAngularFromStartZ = imuAngularRotationZCur - imuAngularRotationZLast;imuAngularRotationXLast = imuAngularRotationXCur;imuAngularRotationYLast = imuAngularRotationYCur;imuAngularRotationZLast = imuAngularRotationZCur;updateImuRollPitchYawStartSinCos();} else {VeloToStartIMU();TransformToStartIMU(&point);}}segmentedCloud->points[i] = point;}imuPointerLastIteration = imuPointerLast;}

VeloToStartIMU()函数

==因为对应的velocity数据是在world坐标系下的,所以imuVeloFromStartXCur存在的坐标系也是world坐标系下的,因此,如果要转到start坐标系,需要先转移到IMU坐标系,然后在转移到start imu的坐标系 ==
**world坐标系到IMU坐标系的变换满足roll (Z)->pitch(X) ->yaw(Y) ,得到的变换如下图所示: **
请添加图片描述

    void VeloToStartIMU(){imuVeloFromStartXCur = imuVeloXCur - imuVeloXStart;//current time to start timeimuVeloFromStartYCur = imuVeloYCur - imuVeloYStart;imuVeloFromStartZCur = imuVeloZCur - imuVeloZStart;
//新的坐标系Y为yaw ->yaw的转置float x1 = cosImuYawStart * imuVeloFromStartXCur - sinImuYawStart * imuVeloFromStartZCur;float y1 = imuVeloFromStartYCur;float z1 = sinImuYawStart * imuVeloFromStartXCur + cosImuYawStart * imuVeloFromStartZCur;
//新的坐标系X为pitch->X的转置float x2 = x1;float y2 = cosImuPitchStart * y1 + sinImuPitchStart * z1;float z2 = -sinImuPitchStart * y1 + cosImuPitchStart * z1;
//新的坐标系Z为roll ->Z的转置imuVeloFromStartXCur = cosImuRollStart * x2 + sinImuRollStart * y2;imuVeloFromStartYCur = -sinImuRollStart * x2 + cosImuRollStart * y2;imuVeloFromStartZCur = z2;}

TransformToStartIMU(PointType *p)

函数首先通过yaw(Y)->pitch(X)->roll(Z)的右乘转到world坐标系,然后再进行world 到 start imu的转换(YawT)->(PitchT)->(RollT)因为是固定坐标系的旋转所以执行的乘法为左乘(Y->X->Z)最终得到变换的结果

    void TransformToStartIMU(PointType *p){float x1 = cos(imuRollCur) * p->x - sin(imuRollCur) * p->y;float y1 = sin(imuRollCur) * p->x + cos(imuRollCur) * p->y;float z1 = p->z;float x2 = x1;float y2 = cos(imuPitchCur) * y1 - sin(imuPitchCur) * z1;float z2 = sin(imuPitchCur) * y1 + cos(imuPitchCur) * z1;float x3 = cos(imuYawCur) * x2 + sin(imuYawCur) * z2;float y3 = y2;float z3 = -sin(imuYawCur) * x2 + cos(imuYawCur) * z2;float x4 = cosImuYawStart * x3 - sinImuYawStart * z3;float y4 = y3;float z4 = sinImuYawStart * x3 + cosImuYawStart * z3;float x5 = x4;float y5 = cosImuPitchStart * y4 + sinImuPitchStart * z4;float z5 = -sinImuPitchStart * y4 + cosImuPitchStart * z4;p->x = cosImuRollStart * x5 + sinImuRollStart * y5 + imuShiftFromStartXCur;p->y = -sinImuRollStart * x5 + cosImuRollStart * y5 + imuShiftFromStartYCur;p->z = z5 + imuShiftFromStartZCur;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PostgreSQL 数据备份与恢复:掌握 pg_dump 和 pg_restore 的最佳实践

title: PostgreSQL 数据备份与恢复:掌握 pg_dump 和 pg_restore 的最佳实践 date: 2025/1/28 updated: 2025/1/28 author: cmdragon excerpt: 在数据库管理中,备份与恢复是确保数据安全和业务连续性的关键措施。PostgreSQL 提供了一系列工具,以便于数据库管理员对数据进行…

接口 V2 完善:分布式环境下的 WebSocket 实现与 Token 校验

&#x1f3af; 本文档详细介绍了如何使用WebSocket协议优化客户端与服务端之间的通信&#xff0c;特别是在处理异步订单创建通知的场景中。通过引入WebSocket代替传统的HTTP请求-响应模式&#xff0c;实现了服务器主动向客户端推送数据的功能&#xff0c;极大地提高了实时性和效…

HarmonyOS NEXT:保存应用数据

用户首选项使用 用户首选项的特点 数据体积小、访问频率高、有加载速度要求的数据如用户偏好设置、用户字体大小、应用的配置参数。 用户搜选项&#xff08;Preferences&#xff09;提供了轻量级配置数据的持久化能力&#xff0c;支持订阅数据变化的通知能力。不支持分布式同…

win10部署本地deepseek-r1,chatbox,deepseek联网(谷歌网页插件Page Assist)

win10部署本地deepseek-r1&#xff0c;chatbox&#xff0c;deepseek联网&#xff08;谷歌网页插件Page Assist&#xff09; 前言一、本地部署DeepSeek-r1step1 安装ollamastep2 下载deepseek-r1step2.1 找到模型deepseek-r1step2.2 cmd里粘贴 后按回车&#xff0c;进行下载 ste…

5.3.2 软件设计原则

文章目录 抽象模块化信息隐蔽与独立性衡量 软件设计原则&#xff1a;抽象、模块化、信息隐蔽。 抽象 抽象是抽出事物本质的共同特性。过程抽象是指将一个明确定义功能的操作当作单个实体看待。数据抽象是对数据的类型、操作、取值范围进行定义&#xff0c;然后通过这些操作对数…

4-图像梯度计算

文章目录 4.图像梯度计算(1)Sobel算子(2)梯度计算方法(3)Scharr与Laplacian算子4.图像梯度计算 (1)Sobel算子 图像梯度-Sobel算子 Sobel算子是一种经典的图像边缘检测算子,广泛应用于图像处理和计算机视觉领域。以下是关于Sobel算子的详细介绍: 基本原理 Sobel算子…

图漾相机-ROS2-SDK-Ubuntu版本编译(新版本)

文章目录 前言1.Camport ROS2 SDK 介绍1.1 Camport ROS2 SDK源文件介绍1.2 Camport ROS2 SDK工作流程1.2.1 包含头文件1.2.2 2 初始化 ROS 2 节点1.2.3 创建节点对象1.2.4 创建发布者对象并实现发布逻辑1.2.5 启动 ROS 2 1.3 ROS2 SDK环境配置与编译1.3.1 Ubuntu 20.04 下ROS2 …

海外问卷调查渠道查:企业经营的利器

一、海外问卷调查的基本概念 市场&#xff1a;市场主要由需求者和供给者组成的一种经济关系&#xff0c;主要是商品和服务的交换的一种方式和手段&#xff0c;市场类型按不同标准来划分。按地域划分&#xff0c;则分为国内市场和国际市场&#xff0c;按照产品类型划分&#xf…

向上调整算法(详解)c++

算法流程&#xff1a; 与⽗结点的权值作⽐较&#xff0c;如果⽐它⼤&#xff0c;就与⽗亲交换&#xff1b; 交换完之后&#xff0c;重复 1 操作&#xff0c;直到⽐⽗亲⼩&#xff0c;或者换到根节点的位置 这里为什么插入85完后合法&#xff1f; 我们插入一个85&#xff0c;…

LeetCode题练习与总结:根据二叉树创建字符串--606

一、题目描述 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 "()" 表示&#xff0c;转化后需要省略所有不影响字符串与原始二叉树…

人工智能入门课【手写自注意力机制】

原理 自注意力&#xff08;Self-Attention&#xff09;是一种强大的机制&#xff0c;广泛应用于自然语言处理、计算机视觉等领域&#xff0c;尤其是在Transformer架构中发挥了关键作用。它的核心思想是让模型能够动态地关注输入序列中不同位置之间的关系&#xff0c;从而更好地…

gentoo 中更改$PS1

现象&#xff1a;gentoo linux Xfce桌面&#xff0c;Terminal 终端&#xff0c;当进入很深的目录时&#xff0c;终端提示符会很长&#xff0c;不方便。如下图所示&#xff1a; 故需要修改$PS1 gentoo 默认的 PS1 在 /etc/bash/bashrc .d/10-gentoo-color.bash中定义&a…

安全防护前置

就业概述 网络安全工程师/安全运维工程师/安全工程师 安全架构师/安全专员/研究院&#xff08;数学要好&#xff09; 厂商工程师&#xff08;售前/售后&#xff09; 系统集成工程师&#xff08;所有计算机知识都要会一点&#xff09; 学习目标 前言 网络安全事件 蠕虫病毒--&…

【自然语言处理(NLP)】深度学习架构:Transformer 原理及代码实现

文章目录 介绍Transformer核心组件架构图编码器&#xff08;Encoder&#xff09;解码器&#xff08;Decoder&#xff09; 优点应用代码实现导包基于位置的前馈网络残差连接后进行层规范化编码器 Block编码器解码器 Block解码器训练预测 个人主页&#xff1a;道友老李 欢迎加入社…

mysqldump+-binlog增量备份

注意&#xff1a;二进制文件删除必须使用help purge 不可用rm -f 会崩 一、概念 增量备份&#xff1a;仅备份上次备份以后变化的数据 差异备份&#xff1a;仅备份上次完全备份以后变化的数据 完全备份&#xff1a;顾名思义&#xff0c;将数据完全备份 其中&#xff0c;…

cf集合***

当周cf集合&#xff0c;我也不知道是不是当周的了&#xff0c;麻了&#xff0c;下下周争取写到e补f C. Kevin and Puzzle&#xff08;999&#xff09; 题解&#xff1a;一眼动态规划&#xff0c;但是具体这个状态应该如何传递呢&#xff1f; 关键点&#xff1a;撒谎的人不相…

大模型概述(方便不懂技术的人入门)

1 大模型的价值 LLM模型对人类的作用&#xff0c;就是一个百科全书级的助手。有多么地百科全书&#xff0c;则用参数的量来描述&#xff0c; 一般地&#xff0c;大模型的参数越多&#xff0c;则该模型越好。例如&#xff0c;GPT-3有1750亿个参数&#xff0c;GPT-4可能有超过1万…

Linux-CentOS的yum源

1、什么是yum yum是CentOS的软件仓库管理工具。 2、yum的仓库 2.1、yum的远程仓库源 2.1.1、国内仓库 国内较知名的网络源(aliyun源&#xff0c;163源&#xff0c;sohu源&#xff0c;知名大学开源镜像等) 阿里源:https://opsx.alibaba.com/mirror 网易源:http://mirrors.1…

简单易懂的倒排索引详解

文章目录 简单易懂的倒排索引详解一、引言 简单易懂的倒排索引详解二、倒排索引的基本结构三、倒排索引的构建过程四、使用示例1、Mapper函数2、Reducer函数 五、总结 简单易懂的倒排索引详解 一、引言 倒排索引是一种广泛应用于搜索引擎和大数据处理中的数据结构&#xff0c;…

Deepseek智能AI--国产之光

以下是以每个核心问题为独立章节的高质量技术博客整理&#xff0c;采用学术级论述框架并增强可视化呈现&#xff1a; 大型语言模型深度解密&#xff1a;从哲学思辨到系统工程 目录 当服务器关闭&#xff1a;AI的终极告解与技术隐喻情感计算&#xff1a;图灵测试未触及的认知深…