基于ROS2的消除重力加速度对IMU加速度影响,动态获取当前重力加速度。

news2024/11/15 10:53:28

消除重力加速度的影响

  • 受力分析: IMU静止时,与IMU所在平面会有一个向上的支持力(重力反作用力),IMU就会测量的角速度就是反作用力带来的。
  • 坐标关系:IMU在平面或者斜坡,IMU的Z轴都或多或少与重力有一个夹角,因此重力的反作用力(支持力)会按照夹角分配到IMU各个轴上,我们就是将与重力坐标系转到IMU坐标系,如下图所示黑线坐标系转到红线坐标系,图中只展示了三维坐标系的二维形式。
  • 消除重力:将IMU坐标系得到的值减去重力在每个轴上的分量,就能消除重力对加速度的影响。
    在这里插入图片描述
  • 分析已知变量, IMU能获得的数据有三维的加速度以及三维的欧拉角。其中欧拉角就是重力坐标系与IMU坐标系三轴之间的夹角,因此通过欧拉角,按照z、y、x顺序,就能将重力坐标系旋转到IMU坐标系。
    R I G = R z ⋅ R y ⋅ R z R^{G}_{I} = R_{z} \cdot R_{y} \cdot R_{z} RIG=RzRyRz
    其中G表示重力坐标系,也有用W表示的世界坐标系,I为IMU坐标系。 R I G R^{G}_{I} RIG表示从重力坐标系(World)到IMU系的旋转矩阵。
    在这里插入图片描述
    所以将重力加速度转到IMU坐标系下的公式为
    G r a v i t y I ⃗ = R I ⃗ ⋅ G r a v i t y \vec{Gravity_{I}} = \vec{R_{I}} \cdot Gravity GravityI =RI Gravity,其中Gravity是常量,我们设Gravity为9.8左右(后面会用梯度下降算法来求得误差最小的重力加速度)。
    然后用获取的IMU三轴的加速度减去转换到IMU坐标系的加速度得到绝对的加速度(相对于地面静止)。代码如下:
   float accX = msg->linear_acceleration.y - std::sin(roll) * std::cos(pitch) * gravity_;
   float accY = msg->linear_acceleration.z - std::cos(roll) * std::cos(pitch) * gravity_;
   float accZ = msg->linear_acceleration.x + std::sin(pitch) * gravity_;

梯度下降算法求得当地的重力加速度

  • 首先设置一个初始重力加速度,可以设置的大一些,然后设置一个学习率,通过当前误差与理论误差的差为梯度,让初始值沿着梯度下降的方向求得误差,如果误差小于一定的值,那么就保留当前的值。

如下图所示

IMU与水平面有一定的夹角。因此下面的加速度分别是 4.874595 、 -0.502782 、 8.432.378
如果IMU与水平面平行,理论上的值应该是(0,0,9)
因为当前IMU在斜坡上,理论加速度应该为(0,0,0) ,但实际上为(4.874595 , -0.502782 , 8.432.378)。我们要做的就是消除重力的影响。
在这里插入图片描述

在这里插入图片描述
具体代码如下:
imu_processing_node.cpp

#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/imu.hpp>
#include <geometry_msgs/msg/pose_stamped.hpp>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2/convert.h>
#include <nav_msgs/msg/path.hpp>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <iostream>
#include <vector>
#include <mutex>

// 在类中添加私有互斥锁成员
std::mutex mutex_;

class ImuProcessingNode : public rclcpp::Node
{
public:
    ImuProcessingNode() : Node("imu_processing_node")
    {
        std::cout << "ImuProcessingNode" << std::endl;
        imu_subscriber_ = this->create_subscription<sensor_msgs::msg::Imu>(
            "/imu/data_raw", 10, std::bind(&ImuProcessingNode::imuCallback, this, std::placeholders::_1));

        // imu_subscriber_ = this->create_subscription<sensor_msgs::msg::Imu>(
        //     "/imu/data_raw", 10, std::bind(&ImuProcessingNode::calculateCorrectedLinearAcceleration, this, std::placeholders::_1));

        trajectory_publisher_ = this->create_publisher<nav_msgs::msg::Path>( // Use Path message type
            "integrated_trajectory", 10);

        // Initialize necessary variables here
        imu_time_.reserve(imu_que_length_);
        imu_roll_.reserve(imu_que_length_);
        imu_pitch_.reserve(imu_que_length_);
        imu_yaw_.reserve(imu_que_length_);
        imu_acc_x_.reserve(imu_que_length_);
        imu_acc_y_.reserve(imu_que_length_);
        imu_acc_z_.reserve(imu_que_length_);
        imu_angular_velo_x_.reserve(imu_que_length_);
        imu_angular_velo_y_.reserve(imu_que_length_);
        imu_angular_velo_z_.reserve(imu_que_length_);
        imu_shift_x_.reserve(imu_que_length_);
        imu_shift_y_.reserve(imu_que_length_);
        imu_shift_z_.reserve(imu_que_length_);
        imu_velo_x_.reserve(imu_que_length_);
        imu_velo_y_.reserve(imu_que_length_);
        imu_velo_z_.reserve(imu_que_length_);
        imu_angular_rotation_x_.reserve(imu_que_length_);
        imu_angular_rotation_y_.reserve(imu_que_length_);
        imu_angular_rotation_z_.reserve(imu_que_length_);
    }

private:
    double sumXYZ(double x, double y, double z)
    {
        // 计算平方和
        double squared_sum = x * x + y * y + z * z;
        return squared_sum;
    }
    // 在 ImuProcessingNode 类中添加一个新的私有函数来计算矫正后的线性加速度的平方和
    void calculateCorrectedLinearAcceleration(const sensor_msgs::msg::Imu::SharedPtr msg)
    {

        // 使用互斥锁保护代码块
        {
            std::lock_guard<std::mutex> lock(mutex_); // 加锁
            gravity_ = 9.9;
            double roll, pitch, yaw;
            tf2::Quaternion orientation;
            tf2::fromMsg(msg->orientation, orientation);
            tf2::Matrix3x3(orientation).getRPY(roll, pitch, yaw);

            float accX = msg->linear_acceleration.y - std::sin(roll) * std::cos(pitch) * gravity_;
            float accY = msg->linear_acceleration.z - std::cos(roll) * std::cos(pitch) * gravity_;
            float accZ = msg->linear_acceleration.x + std::sin(pitch) * gravity_;

            // 优化步骤
            double target_squared_sum = 0.002; // 目标平方和
            double current_squared_sum = sumXYZ(accX, accY, accZ);
            std::cout << "current_squared_sum::" << current_squared_sum << std::endl;
            int count = 0;
            double zhi = gravity_;
            double sum = 100.0;
            while (current_squared_sum > target_squared_sum) // 当平方和大于目标值时继续优化
            {
                // 使用梯度下降更新 gravity_
                double learning_rate = 0.01;                                // 学习率
                double gradient = current_squared_sum - target_squared_sum; // 梯度
                gravity_ -= learning_rate * gradient;                       // 更新 gravity_
                // std::cout<<"计算次数::"<<count<<"gravity_::"<<gravity_<<" gradient::"<<gradient <<" current_squared_sum::"<<current_squared_sum<<std::endl;
                accX = msg->linear_acceleration.y - std::sin(roll) * std::cos(pitch) * gravity_;
                accY = msg->linear_acceleration.z - std::cos(roll) * std::cos(pitch) * gravity_;
                accZ = msg->linear_acceleration.x + std::sin(pitch) * gravity_;
                count = count + 1;
                if (sum > current_squared_sum)
                {
                    sum = current_squared_sum;
                    zhi = gravity_;
                }
                if (count > 55000)
                {
                    break;
                }
                // // 重新计算矫正后的线性加速度平方和
                current_squared_sum = sumXYZ(accX, accY, accZ);
            }
            if (sum < 0.0021)
            {
                imu_handler = true;
                std::cout << "重力优化"
                          << "error::" << sum << "gravity_::" << zhi << std::endl;
                gravity_ = zhi;
            }
            else
            {
                std::cout << "error::" << sum << "gravity_::" << zhi << std::endl;
            }

        } // 自动解锁
    }
    void AccumulateIMUShiftAndRotation()
    {
        float roll = imu_roll_[imu_pointer_last_];
        float pitch = imu_pitch_[imu_pointer_last_];
        float yaw = imu_yaw_[imu_pointer_last_];
        float accX = imu_acc_x_[imu_pointer_last_];
        float accY = imu_acc_y_[imu_pointer_last_];
        float accZ = imu_acc_z_[imu_pointer_last_];

        float x1 = std::cos(roll) * accX - std::sin(roll) * accY;
        float y1 = std::sin(roll) * accX + std::cos(roll) * accY;
        float z1 = accZ;

        float x2 = x1;
        float y2 = std::cos(pitch) * y1 - std::sin(pitch) * z1;
        float z2 = std::sin(pitch) * y1 + std::cos(pitch) * z1;

        accX = std::cos(yaw) * x2 + std::sin(yaw) * z2;
        accY = y2;
        accZ = -std::sin(yaw) * x2 + std::cos(yaw) * z2;
        std::cout<<"accX::"<<accX<<" accY::"<<accY<<" accZ::"<<accZ <<std::endl;

        int imuPointerBack = (imu_pointer_last_ + imu_que_length_ - 1) % imu_que_length_;
        double timeDiff = imu_time_[imu_pointer_last_] - imu_time_[imuPointerBack];
        // std::cout<<"timeDiff::"<<timeDiff <<" imu_pointer_last_:"<<imu_pointer_last_<<" imuPointerBack:"<<imuPointerBack<<std::endl;
        if (timeDiff < scanPeriod)
        {
            imu_shift_x_[imu_pointer_last_] = imu_shift_x_[imuPointerBack] + imu_velo_x_[imuPointerBack] * timeDiff + accX * timeDiff * timeDiff / 2;
            imu_shift_y_[imu_pointer_last_] = imu_shift_y_[imuPointerBack] + imu_velo_y_[imuPointerBack] * timeDiff + accY * timeDiff * timeDiff / 2;
            imu_shift_z_[imu_pointer_last_] = imu_shift_z_[imuPointerBack] + imu_velo_z_[imuPointerBack] * timeDiff + accZ * timeDiff * timeDiff / 2;

            imu_velo_x_[imu_pointer_last_] = imu_velo_x_[imuPointerBack] + accX * timeDiff;
            imu_velo_y_[imu_pointer_last_] = imu_velo_y_[imuPointerBack] + accY * timeDiff;
            imu_velo_z_[imu_pointer_last_] = imu_velo_z_[imuPointerBack] + accZ * timeDiff;

            imu_angular_rotation_x_[imu_pointer_last_] = imu_angular_rotation_x_[imuPointerBack] + imu_angular_velo_x_[imuPointerBack] * timeDiff;
            imu_angular_rotation_y_[imu_pointer_last_] = imu_angular_rotation_y_[imuPointerBack] + imu_angular_velo_y_[imuPointerBack] * timeDiff;
            imu_angular_rotation_z_[imu_pointer_last_] = imu_angular_rotation_z_[imuPointerBack] + imu_angular_velo_z_[imuPointerBack] * timeDiff;
        }
    }
    void imuCallback(const sensor_msgs::msg::Imu::SharedPtr msg)
    {
        // Print original IMU values
        RCLCPP_INFO(this->get_logger(), "Original IMU Orientation: (%f, %f, %f, %f)",
                    msg->orientation.x, msg->orientation.y, msg->orientation.z, msg->orientation.w);
        RCLCPP_INFO(this->get_logger(), "Original IMU Linear Acceleration: (%f, %f, %f)",
                    msg->linear_acceleration.x, msg->linear_acceleration.y, msg->linear_acceleration.z);
        RCLCPP_INFO(this->get_logger(), "Original IMU Angular Velocity: (%f, %f, %f)",
                    msg->angular_velocity.x, msg->angular_velocity.y, msg->angular_velocity.z);

        // Process IMU data, remove gravity influence, integrate, and publish trajectory
        double roll, pitch, yaw;
        tf2::Quaternion orientation;
        tf2::fromMsg(msg->orientation, orientation);
        tf2::Matrix3x3(orientation).getRPY(roll, pitch, yaw);
        if (!imu_handler)
        {
            calculateCorrectedLinearAcceleration(msg);
        }
        else
        {
            float accX = msg->linear_acceleration.y - std::sin(roll) * std::cos(pitch) * gravity_;
            float accY = msg->linear_acceleration.z - std::cos(roll) * std::cos(pitch) * gravity_;
            float accZ = msg->linear_acceleration.x + std::sin(pitch) * gravity_;

            imu_pointer_last_ = (imu_pointer_last_ + 1) % imu_que_length_;

            imu_time_[imu_pointer_last_] = msg->header.stamp.sec + msg->header.stamp.nanosec * 1e-9;

            imu_roll_[imu_pointer_last_] = roll;
            imu_pitch_[imu_pointer_last_] = pitch;
            imu_yaw_[imu_pointer_last_] = yaw;

            imu_acc_x_[imu_pointer_last_] = accX;
            imu_acc_y_[imu_pointer_last_] = accY;
            imu_acc_z_[imu_pointer_last_] = accZ;

            imu_angular_velo_x_[imu_pointer_last_] = msg->angular_velocity.x;
            imu_angular_velo_y_[imu_pointer_last_] = msg->angular_velocity.y;
            imu_angular_velo_z_[imu_pointer_last_] = msg->angular_velocity.z;

            // Print transformed IMU values
            RCLCPP_INFO(this->get_logger(), "Transformed IMU RPY: (%f, %f, %f)", roll, pitch, yaw);
            RCLCPP_INFO(this->get_logger(), "Transformed IMU Linear Acceleration: (%f, %f, %f)", accX, accY, accZ);

            AccumulateIMUShiftAndRotation();
            // Update variables and publish trajectory using trajectory_publisher_

            // Publish integrated trajectory
            nav_msgs::msg::Path integrated_trajectory;
            integrated_trajectory.header = msg->header;
            integrated_trajectory.header.frame_id = "base_link";

            geometry_msgs::msg::PoseStamped integrated_pose;
            integrated_pose.header = msg->header;
            integrated_pose.pose.position.x = imu_shift_x_[imu_pointer_last_];
            integrated_pose.pose.position.y = imu_shift_y_[imu_pointer_last_];
            integrated_pose.pose.position.z = imu_shift_z_[imu_pointer_last_];

            // Assuming imu_angular_rotation_x_, imu_angular_rotation_y_, imu_angular_rotation_z_
            // contain the integrated orientation values
            tf2::Quaternion orientation1;
            orientation1.setRPY(imu_angular_rotation_x_[imu_pointer_last_],
                                imu_angular_rotation_y_[imu_pointer_last_],
                                imu_angular_rotation_z_[imu_pointer_last_]);
            integrated_pose.pose.orientation = tf2::toMsg(orientation1);
            std::cout<<"x:"<<integrated_pose.pose.position.x<<" y:"<<integrated_pose.pose.position.y<<" z:"<<integrated_pose.pose.position.z<<std::endl;

            integrated_trajectory.poses.push_back(integrated_pose); // Add the pose to the trajectory
            trajectory_publisher_->publish(integrated_trajectory);
        }
    }

    rclcpp::Subscription<sensor_msgs::msg::Imu>::SharedPtr imu_subscriber_;
    rclcpp::Publisher<nav_msgs::msg::Path>::SharedPtr trajectory_publisher_;
    bool imu_handler = false;
    int imu_pointer_last_ = 0;
    float gravity_ = 9.8;
    const int imu_que_length_ = 10;
    double scanPeriod = 0.1;
    std::vector<double> imu_time_;
    std::vector<double> imu_roll_;
    std::vector<double> imu_pitch_;
    std::vector<double> imu_yaw_;
    std::vector<float> imu_acc_x_;
    std::vector<float> imu_acc_y_;
    std::vector<float> imu_acc_z_;
    std::vector<float> imu_angular_velo_x_;
    std::vector<float> imu_angular_velo_y_;
    std::vector<float> imu_angular_velo_z_;
    std::vector<double> imu_shift_x_;
    std::vector<double> imu_shift_y_;
    std::vector<double> imu_shift_z_;
    std::vector<float> imu_velo_x_;
    std::vector<float> imu_velo_y_;
    std::vector<float> imu_velo_z_;
    std::vector<float> imu_angular_rotation_x_;
    std::vector<float> imu_angular_rotation_y_;
    std::vector<float> imu_angular_rotation_z_;
};

int main(int argc, char **argv)
{
    // RCLCPP_INFO("begin", "Start IMU");
    std::cout << "Start IMU" << std::endl;
    rclcpp::init(argc, argv);
    auto node = std::make_shared<ImuProcessingNode>();
    rclcpp::spin(node);
    std::cout << "End IMU" << std::endl;
    rclcpp::shutdown();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.8)
project(my_imu_processing_pkg)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(std_msgs REQUIRED)
find_package(std_srvs REQUIRED)
find_package(tf2 REQUIRED)
find_package(nav_msgs REQUIRED)

set(dependencies
  rclcpp
  sensor_msgs
  std_msgs
  std_srvs
  tf2
  nav_msgs
)

include_directories(include)

add_executable(
  imu_processing_node
  "src/imu_processing_node.cpp"
)

ament_target_dependencies(imu_processing_node ${dependencies})

install(
  TARGETS imu_processing_node
  DESTINATION lib/${PROJECT_NAME}
)

install(
  DIRECTORY launch
  DESTINATION share/${PROJECT_NAME}
)


if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_imu_processing_pkg</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="2267507789@qq.com">philtell</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>
  <depend>rclcpp</depend>
  <depend>sensor_msgs</depend>
  <depend>std_msgs</depend>
  <depend>std_srvs</depend>
  <depend>tf2</depend>
  <depend>nav_msgs</depend>
  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

运行命令为: ros2 run my_imu_processing_pkg imu_processing_node

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

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

相关文章

你真的懂分数吗?(一)——分数的数学结构和建模

早点关注我&#xff0c;精彩不错过&#xff01; 我们小学就学过分数&#xff0c;是指的形如“a / b”的&#xff0c;表达把某对象平均分成b份中的a份那么多的含义的数。自然地&#xff0c;a, b一般都是整数&#xff0c;b ! 0&#xff1b;如果a&#xff0c;b仍然是分数的话&…

【UE】蓝图通信——事件分发器

目标 比如我现在希望点击控件蓝图A中的按钮后&#xff0c;蓝图B能够马上做出响应 实现步骤 1. 这里控件蓝图A叫“UI_按钮”&#xff0c;我在该蓝图中创建了一个名为“btnIsClicked”的事件分发器 当按钮被点击时&#xff0c;就会调用“btnIsClicked” 2. 蓝图B这里叫做“BP_…

Leetcode 剑指 Offer II 041. 滑动窗口的平均值

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个整数数据流和一个窗口大小&#xff0c;根据该滑动窗口的…

Postman —— postman实现参数化

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数每…

【Luniux】解决Ubuntu外接显示器不显示的问题

Luniux】解决Ubuntu外接显示器不显示的问题 文章目录 Luniux】解决Ubuntu外接显示器不显示的问题1. 检查nvidia显卡驱动是否正常2. 更新驱动3. 检查显示器是否能检测到Reference 1. 检查nvidia显卡驱动是否正常 使用命令行 nvidia-smi来检查显卡驱动是否正常&#xff0c;如果…

【ArcGIS微课1000例】0074:ArcGIS热点分析(Getis-Ord Gi*)---犯罪率热点图

严重声明:本文来自专栏《ArcGIS微课1000例:从点滴到精通》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:(https://blog.csdn.net/lucky51222/category_11121281.html),谢绝转载或爬取!!! 文章目录 一、热点分析工具介绍二、ArcGIS热点分析案例1. 普通热点分析2. 加…

运维高级学习--Kubernetes(K8s 1.28.x)部署

一、基础环境配置&#xff08;所有主机操作&#xff09; 主机名规划 序号 主机ip 主机名规划1 192.168.1.30 kubernetes-master.openlab.cn kubernetes-master2 192.168.1.31 kubernetes-node1.openlab.cn kubernetes-node13 192.168.1.32 kubernetes-node2…

华为OD机试 - 按索引范围翻转文章片段 - 字符串(Java 2022 Q4 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

下载的文件被Windows 11 安全中心自动删除

今天从CSDN上下载了自己曾经上传的文件&#xff0c;但是浏览器下载完之后文件被Windows安全中心自动删除&#xff0c;说是带病毒。实际是没有病毒的&#xff0c;再说了即便有病毒也不应该直接删除啊&#xff0c;至少给用户一个保留或删除的选项。 研究了一番&#xff0c;可以暂…

【ArcGIS微课1000例】0072:如何生成空间权重矩阵

严重声明:本文来自专栏《ArcGIS微课1000例:从点滴到精通》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:(https://blog.csdn.net/lucky51222/category_11121281.html),谢绝转载或爬取!!! 文章目录 一、空间权重矩阵工具介绍二、ArcGIS生成空间权重矩阵三、注意事项…

虚拟机软件的优点是什么?缺点又是什么?

虚拟机软件想必对于使用MacBook的小伙伴来说并不陌生&#xff0c;安装上虚拟机后我们就能够模拟Windows的环境从而下载一些Mac不支持的软件。尽管Mac的操作系统用起来流畅快捷&#xff0c;但是在日常使用过程中还是会存在一些不便之处。 很多用户非常依赖使用虚拟机软件&#…

一种IDEA疑难杂症的解决办法

解决办法 重启IDEA 针对于IDEA各种解析&#xff0c;运行时问题&#xff0c;但是无法通过搜索引擎得到答案的问题请试试此方法。 删除根目录下[.idea]文件夹后重启 此文件夹为idea首次导入项目时根据项目情况自动生成的配置文件。方便idea下次更快的解析项目。但是某些情况&a…

java.lang.NullPointerException问题

nullpointerexception可能是哪个地方没加注解 例如Service注解没有加

微信小程序报错: SyntaxError: Cannot use import statement outside a module

微信小程序数据绑定&#xff0c;导包出现了: “SyntaxError: Cannot use import statement outside a module” 排查问题步骤记录&#xff0c;共勉 1.出现问题代码&#xff1a; import {createStoreBindings} from "mobx-miniprogram-bindings"import {store} from …

1. 学习 K8S: Docker 基础

学习 K8S: Docker 基础 1. Docker 的诞生 1.1 首次展示 2013 年 3 月 15 日&#xff0c;在北美的圣克拉拉市召开了一场 Python 开发者社区的主题会议 PyCon&#xff0c;研究和探讨各种 Python 开发技术和应用&#xff0c; 在当天的会议日程快结束时&#xff0c;有一位名为 S…

优化器调整策略

损失函数的作用是衡量模型输出与真实标签的差异。当我们有了这个loss之后&#xff0c;我们就可以通过反向传播机制得到参数的梯度&#xff0c;那么我们如何利用这个梯度进行更新参数使得模型的loss逐渐的降低呢&#xff1f; 优化器的作用 Pytorch的优化器&#xff1a; 管理并…

校对的力量:当专业遇上细节,文字焕发新生

在这个信息爆炸的时代&#xff0c;文字成为了我们传达思想、展现形象的重要工具。从新闻稿、政府材料到商业文档&#xff0c;其背后的准确性和专业性往往决定了信息传递的效果。而保证这一切的&#xff0c;就是细致入微的校对工作。 1.错别字与校对&#xff1a;细节之美 错别字…

单机MySQL的演进

2、单机MySQL的演进 我们当前处于大数据时代&#xff0c;大数据一般的数据库无法进行分析处理了&#xff01;2006年发布了Hadoop 1、单机MySQL的年代 某知名购物网站最开始就是到国外购买的PHP网站&#xff0c;拿过来就能直接使用&#xff0c;到后来也改成了Java。早期网站的数…

【Flutter】Flutter 使用 just_audio 播放音频

【Flutter】Flutter 使用 just_audio 播放音频 文章目录 一、前言二、环境与版本信息三、安装和基本使用四、深入 just_audio五、实际业务中的用法六、完整示例七、总结 一、前言 今天&#xff0c;我要为你介绍一个非常实用的 Flutter 音频处理包——just_audio。这个包不仅功…

IDEA软件安装包分享

目录 一、软件简介 二、软件下载 一、软件简介 IntelliJ IDEA是一款流行的Java集成开发环境&#xff08;IDE&#xff09;&#xff0c;由捷克软件开发公司JetBrains开发。它专为Java开发人员设计&#xff0c;提供了许多高级功能和工具&#xff0c;使得开发人员能够更高效地编写…