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

ORB-SLAM3 从理论到代码实现(四):Optimizer 尺度与重力优化

1. 前言InertialOptimization共有4个重载// Inertial pose-graph void static InertialOptimization(Map *pMap, Eigen::Matrix3d Rwg, double scale, Eigen::Vector3d bg, Eigen::Vector3d ba, bool bMono, Eigen::MatrixXd covInertial, bool bFixedVelfalse, bool bGaussfalse, float priorG 1e2, float priorA 1e6); void static InertialOptimization(Map *pMap, Eigen::Vector3d bg, Eigen::Vector3d ba, float priorG 1e2, float priorA 1e6); void static InertialOptimization(vectorKeyFrame* vpKFs, Eigen::Vector3d bg, Eigen::Vector3d ba, float priorG 1e2, float priorA 1e6); void static InertialOptimization(Map *pMap, Eigen::Matrix3d Rwg, double scale);此处理只介绍其中两个与尺度与重力优化相关的。2. 代码分析2.1. InertialOptimization参数pMap: 当前地图Rwg: 待优化的重力方向scale: 待优化的尺度因子bg: 待优化的陀螺仪偏置 (gyro bias)ba: 待优化的加速计偏置 (accel bias)bMono: 传感器是否为单目的标记位在调用时设置为truecovInertial: 惯导协方差矩阵貌似无用bFixedVel: 是否固定关键帧速度不优化的标记位falsebGuass: 惯导噪声是否符合高斯分布的标记位falsepriorG: 陀螺仪偏置优化权重priorA: 加速计偏置优化权重。void Optimizer::InertialOptimization(Map *pMap, Eigen::Matrix3d Rwg, double scale, Eigen::Vector3d bg, Eigen::Vector3d ba, bool bMono, Eigen::MatrixXd covInertial, bool bFixedVel, bool bGauss, float priorG, float priorA) { Verbose::PrintMess(inertial optimization, Verbose::VERBOSITY_NORMAL); int its 200; // Check number of iterations long unsigned int maxKFid pMap-GetMaxKFid(); const vectorKeyFrame * vpKFs pMap-GetAllKeyFrames(); // 获取所有关键帧 // Setup optimizer // 1. 构建优化器 g2o::SparseOptimizer optimizer; g2o::BlockSolverX::LinearSolverType *linearSolver; linearSolver new g2o::LinearSolverEigeng2o::BlockSolverX::PoseMatrixType(); g2o::BlockSolverX *solver_ptr new g2o::BlockSolverX(linearSolver); g2o::OptimizationAlgorithmLevenberg *solver new g2o::OptimizationAlgorithmLevenberg(solver_ptr); if (priorG ! 0.f) solver-setUserLambdaInit(1e3); optimizer.setAlgorithm(solver); // Set KeyFrame vertices (fixed poses and optimizable velocities) // 2. 确定关键帧节点锁住的位姿及可优化的速度 for (size_t i 0; i vpKFs.size(); i) { KeyFrame *pKFi vpKFs[i]; // 跳过id大于当前地图最大id的关键帧 if (pKFi-mnId maxKFid) continue; VertexPose *VP new VertexPose(pKFi); // 继承于public g2o::BaseVertex6, ImuCamPose VP-setId(pKFi-mnId); VP-setFixed(true); optimizer.addVertex(VP); VertexVelocity *VV new VertexVelocity(pKFi); // 继承于public g2o::BaseVertex3, Eigen::Vector3d VV-setId(maxKFid (pKFi-mnId) 1); if (bFixedVel) VV-setFixed(true); else VV-setFixed(false); optimizer.addVertex(VV); } // Biases // 3. 确定偏置节点陀螺仪与加速度计 VertexGyroBias *VG new VertexGyroBias(vpKFs.front()); VG-setId(maxKFid * 2 2); if (bFixedVel) VG-setFixed(true); else VG-setFixed(false); optimizer.addVertex(VG); VertexAccBias *VA new VertexAccBias(vpKFs.front()); VA-setId(maxKFid * 2 3); if (bFixedVel) VA-setFixed(true); else VA-setFixed(false); optimizer.addVertex(VA); // prior acc bias // 4. 添加关于加速度计与陀螺仪偏置的边这两个边加入是保证第一帧的偏置为0 EdgePriorAcc *epa new EdgePriorAcc(cv::Mat::zeros(3, 1, CV_32F)); epa-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VA)); double infoPriorA priorA; epa-setInformation(infoPriorA * Eigen::Matrix3d::Identity()); optimizer.addEdge(epa); EdgePriorGyro *epg new EdgePriorGyro(cv::Mat::zeros(3, 1, CV_32F)); epg-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VG)); double infoPriorG priorG; epg-setInformation(infoPriorG * Eigen::Matrix3d::Identity()); optimizer.addEdge(epg); // Gravity and scale // 5. 添加关于重力方向与尺度的节点 VertexGDir *VGDir new VertexGDir(Rwg); VGDir-setId(maxKFid * 2 4); VGDir-setFixed(false); optimizer.addVertex(VGDir); VertexScale *VS new VertexScale(scale); VS-setId(maxKFid * 2 5); VS-setFixed(!bMono); // Fixed for stereo case optimizer.addVertex(VS); // Graph edges // IMU links with gravity and scale // 6. imu信息链接重力方向与尺度信息 vectorEdgeInertialGS * vpei; // 后面虽然加入了边但是没有用到应该调试用的 vpei.reserve(vpKFs.size()); vectorpairKeyFrame *, KeyFrame * vppUsedKF; vppUsedKF.reserve(vpKFs.size()); // 后面虽然加入了关键帧但是没有用到应该调试用的 std::cout build optimization graph std::endl; for (size_t i 0; i vpKFs.size(); i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mPrevKF pKFi-mnId maxKFid) { if (pKFi-isBad() || pKFi-mPrevKF-mnId maxKFid) continue; if (!pKFi-mpImuPreintegrated) std::cout Not preintegrated measurement std::endl; // 到这里的条件是pKFi是好的并且它有上一个关键帧且他们的id要小于最大id // 6.1 检查节点指针是否为空 // 将pKFi偏置设定为上一关键帧的偏置 pKFi-mpImuPreintegrated-SetNewBias(pKFi-mPrevKF-GetImuBias()); g2o::HyperGraph::Vertex *VP1 optimizer.vertex(pKFi-mPrevKF-mnId); g2o::HyperGraph::Vertex *VV1 optimizer.vertex(maxKFid (pKFi-mPrevKF-mnId) 1); g2o::HyperGraph::Vertex *VP2 optimizer.vertex(pKFi-mnId); g2o::HyperGraph::Vertex *VV2 optimizer.vertex(maxKFid (pKFi-mnId) 1); g2o::HyperGraph::Vertex *VG optimizer.vertex(maxKFid * 2 2); g2o::HyperGraph::Vertex *VA optimizer.vertex(maxKFid * 2 3); g2o::HyperGraph::Vertex *VGDir optimizer.vertex(maxKFid * 2 4); g2o::HyperGraph::Vertex *VS optimizer.vertex(maxKFid * 2 5); if (!VP1 || !VV1 || !VG || !VA || !VP2 || !VV2 || !VGDir || !VS) { cout Error VP1 , VV1 , VG , VA , VP2 , VV2 , VGDir , VS endl; continue; } // 6.2 这是一个大边。。。。包含了上面所有信息注意到前面的两个偏置也做了两个一元边加入 EdgeInertialGS *ei new EdgeInertialGS(pKFi-mpImuPreintegrated); ei-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VP1)); ei-setVertex(1, dynamic_castg2o::OptimizableGraph::Vertex *(VV1)); ei-setVertex(2, dynamic_castg2o::OptimizableGraph::Vertex *(VG)); ei-setVertex(3, dynamic_castg2o::OptimizableGraph::Vertex *(VA)); ei-setVertex(4, dynamic_castg2o::OptimizableGraph::Vertex *(VP2)); ei-setVertex(5, dynamic_castg2o::OptimizableGraph::Vertex *(VV2)); ei-setVertex(6, dynamic_castg2o::OptimizableGraph::Vertex *(VGDir)); ei-setVertex(7, dynamic_castg2o::OptimizableGraph::Vertex *(VS)); vpei.push_back(ei); vppUsedKF.push_back(make_pair(pKFi-mPrevKF, pKFi)); optimizer.addEdge(ei); } } // Compute error for different scales std::setg2o::HyperGraph::Edge * setEdges optimizer.edges(); std::cout start optimization std::endl; optimizer.initializeOptimization(); optimizer.setVerbose(false); optimizer.optimize(its); std::cout end optimization std::endl; // 7. 取数 scale VS-estimate(); // Recover optimized data // Biases VG static_castVertexGyroBias *(optimizer.vertex(maxKFid * 2 2)); VA static_castVertexAccBias *(optimizer.vertex(maxKFid * 2 3)); Vector6d vb; vb VG-estimate(), VA-estimate(); bg VG-estimate(); ba VA-estimate(); scale VS-estimate(); IMU::Bias b(vb[3], vb[4], vb[5], vb[0], vb[1], vb[2]); Rwg VGDir-estimate().Rwg; cv::Mat cvbg Converter::toCvMat(bg); // Keyframes velocities and biases const int N vpKFs.size(); for (size_t i 0; i N; i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mnId maxKFid) continue; VertexVelocity *VV static_castVertexVelocity *(optimizer.vertex(maxKFid (pKFi-mnId) 1)); Eigen::Vector3d Vw VV-estimate(); // Velocity is scaled after pKFi-SetVelocity(Converter::toCvMat(Vw)); if (cv::norm(pKFi-GetGyroBias() - cvbg) 0.01) { pKFi-SetNewBias(b); if (pKFi-mpImuPreintegrated) pKFi-mpImuPreintegrated-Reintegrate(); } else pKFi-SetNewBias(b); } }2.2. InertialOptimizationLoopClosing::MergeLocal2 中使用跟参数最多的那个同名函数不同的地方在于很多节点不可选是否固定优化的目标有速度偏置void Optimizer::InertialOptimization(Map *pMap, Eigen::Vector3d bg, Eigen::Vector3d ba, float priorG, float priorA) { int its 200; long unsigned int maxKFid pMap-GetMaxKFid(); const vectorKeyFrame * vpKFs pMap-GetAllKeyFrames(); // Setup optimizer // 1. 构建优化器 g2o::SparseOptimizer optimizer; g2o::BlockSolverX::LinearSolverType *linearSolver; linearSolver new g2o::LinearSolverEigeng2o::BlockSolverX::PoseMatrixType(); g2o::BlockSolverX *solver_ptr new g2o::BlockSolverX(linearSolver); g2o::OptimizationAlgorithmLevenberg *solver new g2o::OptimizationAlgorithmLevenberg(solver_ptr); solver-setUserLambdaInit(1e3); optimizer.setAlgorithm(solver); // Set KeyFrame vertices (fixed poses and optimizable velocities) // 2. 构建节点固定rt for (size_t i 0; i vpKFs.size(); i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mnId maxKFid) continue; VertexPose *VP new VertexPose(pKFi); VP-setId(pKFi-mnId); VP-setFixed(true); optimizer.addVertex(VP); VertexVelocity *VV new VertexVelocity(pKFi); VV-setId(maxKFid (pKFi-mnId) 1); VV-setFixed(false); optimizer.addVertex(VV); } // Biases // 3. 第一个关键帧的偏置 VertexGyroBias *VG new VertexGyroBias(vpKFs.front()); VG-setId(maxKFid * 2 2); VG-setFixed(false); optimizer.addVertex(VG); VertexAccBias *VA new VertexAccBias(vpKFs.front()); VA-setId(maxKFid * 2 3); VA-setFixed(false); optimizer.addVertex(VA); // prior acc bias // 4. 先验边让偏置趋向于0 EdgePriorAcc *epa new EdgePriorAcc(cv::Mat::zeros(3, 1, CV_32F)); epa-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VA)); double infoPriorA priorA; epa-setInformation(infoPriorA * Eigen::Matrix3d::Identity()); optimizer.addEdge(epa); EdgePriorGyro *epg new EdgePriorGyro(cv::Mat::zeros(3, 1, CV_32F)); epg-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VG)); double infoPriorG priorG; epg-setInformation(infoPriorG * Eigen::Matrix3d::Identity()); optimizer.addEdge(epg); // Gravity and scale // 5. 注意这里固定了尺度与重力方向所以只优化了偏置与速度 VertexGDir *VGDir new VertexGDir(Eigen::Matrix3d::Identity()); VGDir-setId(maxKFid * 2 4); VGDir-setFixed(true); optimizer.addVertex(VGDir); VertexScale *VS new VertexScale(1.0); VS-setId(maxKFid * 2 5); VS-setFixed(true); // Fixed since scale is obtained from already well initialized map optimizer.addVertex(VS); // Graph edges // IMU links with gravity and scale vectorEdgeInertialGS * vpei; vpei.reserve(vpKFs.size()); vectorpairKeyFrame *, KeyFrame * vppUsedKF; vppUsedKF.reserve(vpKFs.size()); // 6. 设置残差边 for (size_t i 0; i vpKFs.size(); i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mPrevKF pKFi-mnId maxKFid) { if (pKFi-isBad() || pKFi-mPrevKF-mnId maxKFid) continue; pKFi-mpImuPreintegrated-SetNewBias(pKFi-mPrevKF-GetImuBias()); g2o::HyperGraph::Vertex *VP1 optimizer.vertex(pKFi-mPrevKF-mnId); g2o::HyperGraph::Vertex *VV1 optimizer.vertex(maxKFid (pKFi-mPrevKF-mnId) 1); g2o::HyperGraph::Vertex *VP2 optimizer.vertex(pKFi-mnId); g2o::HyperGraph::Vertex *VV2 optimizer.vertex(maxKFid (pKFi-mnId) 1); g2o::HyperGraph::Vertex *VG optimizer.vertex(maxKFid * 2 2); g2o::HyperGraph::Vertex *VA optimizer.vertex(maxKFid * 2 3); g2o::HyperGraph::Vertex *VGDir optimizer.vertex(maxKFid * 2 4); g2o::HyperGraph::Vertex *VS optimizer.vertex(maxKFid * 2 5); if (!VP1 || !VV1 || !VG || !VA || !VP2 || !VV2 || !VGDir || !VS) { cout Error VP1 , VV1 , VG , VA , VP2 , VV2 , VGDir , VS endl; continue; } EdgeInertialGS *ei new EdgeInertialGS(pKFi-mpImuPreintegrated); ei-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VP1)); ei-setVertex(1, dynamic_castg2o::OptimizableGraph::Vertex *(VV1)); ei-setVertex(2, dynamic_castg2o::OptimizableGraph::Vertex *(VG)); ei-setVertex(3, dynamic_castg2o::OptimizableGraph::Vertex *(VA)); ei-setVertex(4, dynamic_castg2o::OptimizableGraph::Vertex *(VP2)); ei-setVertex(5, dynamic_castg2o::OptimizableGraph::Vertex *(VV2)); ei-setVertex(6, dynamic_castg2o::OptimizableGraph::Vertex *(VGDir)); ei-setVertex(7, dynamic_castg2o::OptimizableGraph::Vertex *(VS)); vpei.push_back(ei); vppUsedKF.push_back(make_pair(pKFi-mPrevKF, pKFi)); optimizer.addEdge(ei); } } // 7. 优化 // Compute error for different scales optimizer.setVerbose(false); optimizer.initializeOptimization(); optimizer.optimize(its); // 8. 取数 // Recover optimized data // Biases VG static_castVertexGyroBias *(optimizer.vertex(maxKFid * 2 2)); VA static_castVertexAccBias *(optimizer.vertex(maxKFid * 2 3)); Vector6d vb; vb VG-estimate(), VA-estimate(); bg VG-estimate(); ba VA-estimate(); IMU::Bias b(vb[3], vb[4], vb[5], vb[0], vb[1], vb[2]); cv::Mat cvbg Converter::toCvMat(bg); // Keyframes velocities and biases const int N vpKFs.size(); for (size_t i 0; i N; i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mnId maxKFid) continue; VertexVelocity *VV static_castVertexVelocity *(optimizer.vertex(maxKFid (pKFi-mnId) 1)); Eigen::Vector3d Vw VV-estimate(); pKFi-SetVelocity(Converter::toCvMat(Vw)); if (cv::norm(pKFi-GetGyroBias() - cvbg) 0.01) { pKFi-SetNewBias(b); if (pKFi-mpImuPreintegrated) pKFi-mpImuPreintegrated-Reintegrate(); } else pKFi-SetNewBias(b); } }优化重力方向与尺度LocalMapping::ScaleRefinement()中使用优化目标有重力方向与尺度void Optimizer::InertialOptimization(Map *pMap, Eigen::Matrix3d Rwg, double scale) { int its 10; long unsigned int maxKFid pMap-GetMaxKFid(); const vectorKeyFrame * vpKFs pMap-GetAllKeyFrames(); // 1. 构建优化器 // Setup optimizer g2o::SparseOptimizer optimizer; g2o::BlockSolverX::LinearSolverType *linearSolver; linearSolver new g2o::LinearSolverEigeng2o::BlockSolverX::PoseMatrixType(); g2o::BlockSolverX *solver_ptr new g2o::BlockSolverX(linearSolver); g2o::OptimizationAlgorithmGaussNewton *solver new g2o::OptimizationAlgorithmGaussNewton(solver_ptr); optimizer.setAlgorithm(solver); // Set KeyFrame vertices (all variables are fixed) // 2. 添加帧节点其中包括位姿速度两个偏置 for (size_t i 0; i vpKFs.size(); i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mnId maxKFid) continue; VertexPose *VP new VertexPose(pKFi); VP-setId(pKFi-mnId); VP-setFixed(true); optimizer.addVertex(VP); VertexVelocity *VV new VertexVelocity(pKFi); VV-setId(maxKFid 1 (pKFi-mnId)); VV-setFixed(true); optimizer.addVertex(VV); // Vertex of fixed biases VertexGyroBias *VG new VertexGyroBias(vpKFs.front()); VG-setId(2 * (maxKFid 1) (pKFi-mnId)); VG-setFixed(true); optimizer.addVertex(VG); VertexAccBias *VA new VertexAccBias(vpKFs.front()); VA-setId(3 * (maxKFid 1) (pKFi-mnId)); VA-setFixed(true); optimizer.addVertex(VA); } // 3. 添加重力方向与尺度的节点为优化对象 // Gravity and scale VertexGDir *VGDir new VertexGDir(Rwg); VGDir-setId(4 * (maxKFid 1)); VGDir-setFixed(false); optimizer.addVertex(VGDir); VertexScale *VS new VertexScale(scale); VS-setId(4 * (maxKFid 1) 1); VS-setFixed(false); optimizer.addVertex(VS); // Graph edges // 4. 添加边 for (size_t i 0; i vpKFs.size(); i) { KeyFrame *pKFi vpKFs[i]; if (pKFi-mPrevKF pKFi-mnId maxKFid) { if (pKFi-isBad() || pKFi-mPrevKF-mnId maxKFid) continue; g2o::HyperGraph::Vertex *VP1 optimizer.vertex(pKFi-mPrevKF-mnId); g2o::HyperGraph::Vertex *VV1 optimizer.vertex((maxKFid 1) pKFi-mPrevKF-mnId); g2o::HyperGraph::Vertex *VP2 optimizer.vertex(pKFi-mnId); g2o::HyperGraph::Vertex *VV2 optimizer.vertex((maxKFid 1) pKFi-mnId); g2o::HyperGraph::Vertex *VG optimizer.vertex(2 * (maxKFid 1) pKFi-mPrevKF-mnId); g2o::HyperGraph::Vertex *VA optimizer.vertex(3 * (maxKFid 1) pKFi-mPrevKF-mnId); g2o::HyperGraph::Vertex *VGDir optimizer.vertex(4 * (maxKFid 1)); g2o::HyperGraph::Vertex *VS optimizer.vertex(4 * (maxKFid 1) 1); if (!VP1 || !VV1 || !VG || !VA || !VP2 || !VV2 || !VGDir || !VS) { Verbose::PrintMess(Error to_string(VP1-id()) , to_string(VV1-id()) , to_string(VG-id()) , to_string(VA-id()) , to_string(VP2-id()) , to_string(VV2-id()) , to_string(VGDir-id()) , to_string(VS-id()), Verbose::VERBOSITY_NORMAL); continue; } EdgeInertialGS *ei new EdgeInertialGS(pKFi-mpImuPreintegrated); ei-setVertex(0, dynamic_castg2o::OptimizableGraph::Vertex *(VP1)); ei-setVertex(1, dynamic_castg2o::OptimizableGraph::Vertex *(VV1)); ei-setVertex(2, dynamic_castg2o::OptimizableGraph::Vertex *(VG)); ei-setVertex(3, dynamic_castg2o::OptimizableGraph::Vertex *(VA)); ei-setVertex(4, dynamic_castg2o::OptimizableGraph::Vertex *(VP2)); ei-setVertex(5, dynamic_castg2o::OptimizableGraph::Vertex *(VV2)); ei-setVertex(6, dynamic_castg2o::OptimizableGraph::Vertex *(VGDir)); ei-setVertex(7, dynamic_castg2o::OptimizableGraph::Vertex *(VS)); optimizer.addEdge(ei); } } // 5. 优化 // Compute error for different scales optimizer.setVerbose(false); optimizer.initializeOptimization(); optimizer.optimize(its); // Recover optimized data // 6. 取数 scale VS-estimate(); Rwg VGDir-estimate().Rwg; }参考文献【SLAM学习笔记】9-ORB_SLAM3关键源码分析⑦ Optimizer四尺度与重力优化_口哨糖youri的博客-CSDN博客ORB-SLAM3InertialOptimization()代码分析_Zirong.的博客-CSDN博客ORB_SLAM3与VINS_MONO的惯导部分比较以及尺度因子优化分析_Leon Goretzka的博客-CSDN博客

相关文章:

ORB-SLAM3 从理论到代码实现(四):Optimizer 尺度与重力优化

1. 前言 InertialOptimization共有4个重载 // Inertial pose-graph void static InertialOptimization(Map *pMap, Eigen::Matrix3d &Rwg, double &scale, Eigen::Vector3d &bg, Eigen::Vector3d &ba, bool bMono, Eigen::MatrixXd &covInertial, bool …...

Nginx配置实战:手把手教你修复CSP、X-XSS-Protection等10个常见安全响应头漏洞

Nginx安全响应头配置实战:10个关键漏洞修复指南 当安全扫描工具在你的Nginx服务器上标记出一连串"响应头缺失"警告时,那种感觉就像发现自家大门没锁一样令人不安。我曾为一家电商平台做安全审计,他们的扫描报告显示缺少8个关键安全…...

可重构软件无线电平台软硬件实现方法【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)基于Zynq SoC的动态部分可重构基带处理架构&#x…...

HomeSpan实战:如何用Arduino IDE构建多功能智能家居配件

HomeSpan实战:如何用Arduino IDE构建多功能智能家居配件 【免费下载链接】HomeSpan HomeKit Library for the Arduino-ESP32 项目地址: https://gitcode.com/gh_mirrors/ho/HomeSpan HomeSpan是一款专为Arduino-ESP32设计的HomeKit库,它能帮助开发…...

tabula-java扩展开发指南:如何实现自定义表格提取算法

tabula-java扩展开发指南:如何实现自定义表格提取算法 【免费下载链接】tabula-java Extract tables from PDF files 项目地址: https://gitcode.com/gh_mirrors/ta/tabula-java 在处理PDF文件时,从复杂格式中准确提取表格数据一直是开发者面临的…...

车辆换挡缓冲阀结构设计与优化AMESim仿真【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)缓冲阀动力学建模与AMESim参数化仿真:所…...

AI智能体开发新范式:引入节奏与记忆系统优化长期任务执行

1. 项目概述:当AI智能体学会“呼吸”与“节奏”在AI智能体开发领域,我们常常陷入一个误区:追求极致的单次响应速度与逻辑推理的深度,却忽略了智能体作为一个持续运行的“生命体”所应有的“节奏感”。想象一下,一个不知…...

ighack高级配置技巧:如何优化攻击性能与匿名性

ighack高级配置技巧:如何优化攻击性能与匿名性 【免费下载链接】ighack Hack Instagram From Termux With Help of Tor 项目地址: https://gitcode.com/gh_mirrors/ig/ighack ighack是一款专为Termux环境设计的Instagram攻击工具,通过Tor网络提供…...

Rust版LangChain:llm-chain构建高性能LLM应用实践

1. 项目概述:为什么我们需要一个Rust版的LangChain?如果你最近在折腾大语言模型应用,大概率听说过LangChain。它用Python写成,通过“链”的概念把提示词、工具调用、记忆管理这些功能串起来,让构建复杂AI应用变得像搭积…...

Unity Timeline实战:用自定义对话轨道打造电影级游戏过场动画(附完整资源)

Unity Timeline实战:用自定义对话轨道打造电影级游戏过场动画(附完整资源) 在《巫师3》的凯尔莫罕雪夜对话中,杰洛特与叶奈法的眼神交错配合台词节奏的微妙停顿,让玩家仿佛置身于真实的电影场景。这种沉浸式叙事体验的…...

构建企业级.NET代码编辑器:ScintillaNET终极架构解析

构建企业级.NET代码编辑器:ScintillaNET终极架构解析 【免费下载链接】ScintillaNET A Windows Forms control, wrapper, and bindings for the Scintilla text editor. 项目地址: https://gitcode.com/gh_mirrors/sc/ScintillaNET 在.NET桌面应用开发领域&a…...

VSCode 2026农业插件开发,从Node.js 20.12到Rust WASM桥接——跨平台低功耗灌溉控制插件落地全链路

更多请点击: https://intelliparadigm.com 第一章:VSCode 2026农业物联网插件开发背景与架构概览 随着精准农业与边缘智能的加速融合,面向田间部署的轻量级开发工具需求激增。VSCode 2026 版本正式将农业物联网(Agri-IoT&#xf…...

ai辅助android开发:让快马帮你编写自定义view与复杂动画

今天在做一个音频可视化功能时,遇到了自定义View绘制动态波形图的难题。作为一个Android开发者,我们都知道自定义View是进阶必备技能,但每次写起来都要处理测量、绘制、动画等一堆细节,特别耗时。好在现在有了AI辅助开发工具&…...

【限时解密】Docker边缘优化“静默失效”现象:当--cgroup-parent被忽略时,K3s集群吞吐量暴跌63%的隐蔽根源

更多请点击: https://intelliparadigm.com 第一章:Docker边缘优化 在资源受限的边缘设备(如树莓派、Jetson Nano 或工业网关)上运行 Docker 容器时,镜像体积、启动延迟与内存占用成为关键瓶颈。传统构建方式生成的镜像…...

西门子PLC数据采集(一):通过.net采集西门子PLC数据的方法

一、前言: (本文对于会一点.net Core开发的PLC自动化工程师及了解西门子PLC的.net 软件开发工程师比较友好) 谈到通过.net Core采集西门子PLC的数据,其实不仅仅涉及到采集,其中还包括数据的存储、展示、分析、数据上…...

Buck电路电感值、电容值计算

0. 结论当然,实际使用的电容计算值要考虑负载的波动,一般来说其电容值要远远大于此计算值1. Buck电路的伏秒平衡通常BUCK芯片的基本拓扑如下:内部集成了开关管以及其驱动器,外围电路包括输入、电感、二极管以及输出电容。图1 与 图…...

macOS Python 安装

目录 一、确认系统环境 二、安装 (一)下载安装包 (二)安装过程 三、配置环境变量 四、验证安装 一、确认系统环境 在安装 Python 之前,我们先简单了解一下自己的 MACOS 系统。可以点击屏幕左上角的苹果菜单&…...

半导体设计数据管理挑战与ENOVIA DesignSync解决方案

1. 半导体设计数据管理的行业挑战与解决方案在当今半导体行业,芯片复杂度正以惊人的速度增长。过去二十年里,芯片复杂度提升了1000倍,而工程师的生产力提升却远远跟不上这一步伐。这种差距导致了开发成本呈指数级增长,同时还要面对…...

揭秘书匠策AI:毕业论文写作的“超级外挂”!

在学术的征途上,毕业论文如同一座巍峨的山峰,让无数学生望而生畏。选题迷茫、资料难寻、逻辑混乱、格式繁琐……这些问题像一道道难以逾越的鸿沟,横亘在每一位即将毕业的学生面前。但别怕,今天我要给大家揭秘一个“超级外挂”——…...

需要抢答器功能?知识竞赛软件选购指南

🎯 需要抢答器功能?知识竞赛软件选购指南精准抢答 公平竞技 一键掌控📌 引言无论是学校学科竞赛、企业技能比拼,还是社区趣味活动,一场精彩的知识竞赛都离不开紧张刺激的抢答环节。传统的硬件抢答器存在布线繁琐、设…...

JAVA自营商城小程序APP商城源码单商户源码的uniapp代码片段

以下为JAVA自营商城小程序/APP单商户源码的Uniapp核心功能代码片段&#xff0c;包含商品展示、购物车管理、订单支付等模块&#xff1a;1. 商品列表页&#xff08;pages/product/list.vue&#xff09;vue<template><view class"container"><!-- 搜索栏…...

QMT自动交易逆回购实战:我的资金利用率提升20%的配置心得与三个常见坑

QMT自动交易逆回购实战&#xff1a;我的资金利用率提升20%的配置心得与三个常见坑 在量化交易的世界里&#xff0c;逆回购因其低风险特性成为资金管理的重要工具。但很多QMT用户发现&#xff0c;简单的自动化策略往往无法充分发挥资金效率——你可能遇到过14:58分下单失败、价格…...

AI构建赛博朋克任务控制台:纯前端模拟架构与交互设计解析

1. 项目概述&#xff1a;一个由AI构建的赛博朋克任务控制台如果你和我一样&#xff0c;对科幻电影里那些闪烁着霓虹光芒、数据流实时滚动的任务控制中心着迷&#xff0c;同时又对AI驱动的Web开发充满好奇&#xff0c;那么这个名为“OpenClaw Mission Control v3”的项目绝对值得…...

如何用自然语言构建专属RAG智能体:5分钟快速上手指南

如何用自然语言构建专属RAG智能体&#xff1a;5分钟快速上手指南 【免费下载链接】rags Build ChatGPT over your data, all with natural language 项目地址: https://gitcode.com/gh_mirrors/ra/rags RAGs是一款基于Streamlit开发的应用程序&#xff0c;能够让你通过自…...

无人机巡检中输电线路缺陷检测数据集(YOLO格式)

摘要&#xff1a;本数据集针对输电线路缺陷检测中缺陷特征识别难、人工巡检效率低等问题&#xff0c;构建了包含78,704张图像、356,160个标注框的YOLO格式数据集&#xff0c;涵盖绑线缺陷、并沟线夹缺陷、耐张线夹缺陷、锈蚀缺陷、杆塔损伤五类常见输电线路缺陷&#xff0c;支持…...

终极Voyager代码统计报告:语言分布与复杂度深度分析

终极Voyager代码统计报告&#xff1a;语言分布与复杂度深度分析 【免费下载链接】Voyager An Open-Ended Embodied Agent with Large Language Models 项目地址: https://gitcode.com/gh_mirrors/voya/Voyager Voyager作为一款基于大型语言模型的开放式具身智能体&#…...

d3dxSkinManage缩略图功能终极配置指南:三步搞定个性化皮肤管理

d3dxSkinManage缩略图功能终极配置指南&#xff1a;三步搞定个性化皮肤管理 【免费下载链接】d3dxSkinManage 3dmigoto skin mods manage tool 项目地址: https://gitcode.com/gh_mirrors/d3/d3dxSkinManage 还在为游戏皮肤管理工具的缩略图功能感到困惑吗&#xff1f;d…...

Electron-React-Boilerplate云原生应用:终极部署与扩展指南

Electron-React-Boilerplate云原生应用&#xff1a;终极部署与扩展指南 【免费下载链接】electron-react-boilerplate A Foundation for Scalable Cross-Platform Apps 项目地址: https://gitcode.com/gh_mirrors/el/electron-react-boilerplate Electron-React-Boilerp…...

基于ChatGPT API的私有化AI对话网站:从部署到二次开发全解析

1. 项目概述&#xff1a;一个基于ChatGPT的独立网站最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“Aniuyyds/ChatGPT-website”。光看名字&#xff0c;你可能会觉得这又是一个简单的ChatGPT网页版套壳&#xff0c;但实际扒开代码研究后&#xff0c;我发现它的定位和实现…...

浙江移动魔百盒HM201安装Armbian完整指南:从网络异常到稳定运行的终极解决方案

浙江移动魔百盒HM201安装Armbian完整指南&#xff1a;从网络异常到稳定运行的终极解决方案 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w…...