【7. ROS 中的 IMU 惯性测量单元消息包】
欢迎大家阅读2345VOR的博客【6. 激光雷达接入ROS】🥳🥳🥳
2345VOR鹏鹏主页: 已获得CSDN《嵌入式领域优质创作者》称号👻👻👻,座右铭:脚踏实地,仰望星空🛹🛹🛹
🎏🎏主要开发专栏🎏🎏
《arduino学习》:学习最简单开源便利的单片机Arduino,与时俱进😆😆😆
《Arduino编程参考》:本专栏围绕Arduino语法和Arduino库使用开发;🌻🌻🌻
《 Arduino小项目开发》:本专栏围绕Arduino生态结合实际需求设计综合的小项目开发。🌼🌼🌼
《HomeAssistant》:介绍homeassistant中基本开发, 重点设计esphome和nodered开发,包含小爱同学打印机等诸多设备添加。🎉🎉🎉
本文章属于《Ubuntu学习》和《ROS机器人学习》
:围绕Ubuntu系统基本配置及相关命令行学习记录!机器人操作系统 (ROS) 是一组软件库和工具,可帮助您构建机器人应用程序。👍👍👍
1. 前言
Ubuntu环境搭建
【经典Ubuntu20.04版本U盘安装双系统教程】
【Windows10安装或重装ubuntu18.04双系统教程】
【Ubuntu同步系统时间】
【Ubuntu中截图工具】
【Ubuntu安装QQ】
【Ubuntu安装后基本配置】
【Ubuntu启动菜单的默认项】
【ubuntu系统中修改hosts配置】
【18.04Ubuntu中解决无法识别显示屏】
【ROS 开发神器 Visual Studio Code 的安装和设置】
ROS学习笔记
【1. Ubuntu18.04安装ROS Melodic】
【2. 在Github上寻找安装ROS软件包】
【3. 初学ROS,年轻人的第一个Node节点】
【4. ROS的主要通讯方式:Topic话题与Message消息】
【5. ROS机器人的运动控制】
【6. 激光雷达接入ROS】
【7. ROS 中的 IMU 惯性测量单元消息包】
接下来学习ROS 中的 IMU 惯性测量单元消息包和导航,IMU 惯性测量单元是用来测量机器人的空间姿态!

2. IMU 惯性测量单元
2.1 sensor_msgs
进入ROS Index官网搜索sensor_msgs


进入website

2.2 IMU 惯性测量单元的格式定义
在消息中找到Imu

这就打开了IMU 惯性测量单元的格式定义



3. 使用C++实现IMU获取数据节点
3.1 通用IMU姿态数据格式

直接获取IMU融合好的机器人姿态四元数
3.2 构思功能的思路和步骤
构思

实现步骤
- 构建一个新的软件包,包名叫做imu_pkg。
- 在软件包中新建一个节点,节点名叫做imu_node。
- 在节点中,向ROS大管家NodeHandle申请订阅话题/imu/data,并设置回调函数为IMUCallback()。
- 构建回调函数IMUCallback(),用来接收和处理IMU数据。
- 使用TF工具将四元数转换成欧拉角。
- 调用ROS_INFO()显示转换后的欧拉角数值。
3.3 创建imu_pkg包
在工作空间src文件创建基于sensor_msgs模板的imu_pkg
cd ~/catkin_ws/src/
catkin_create_pkg imu_pkg roscpp rospy sensor_msgs

在imu_pkg文件夹下src中创建imu_node.cpp

3.4 编写imu_node订阅者节点
imu_node源码
#include <ros/ ros.h>
#include <sensor msgs/Imu.h>
#include "tf/tf.h"void IMUCallback(sensor msgs::Imu msg)
{if(msg.orientation_covariance[0] <0)return;tf::Quaternion quaternion(msg.orientation.x,msg.orientation.y,msg.orientation.z,msg.orientation.w);double roll, pitch, yaw;tf::Matrix3x3(quaternion).getRPY( roll, pitch, yaw);roll = roll*180/M_PI;pitch = pitch*180/M_PI;yaw = yaw*180/M_PI;ROS_INFO(“滚转= %.0f 俯仰=%.0f 朝向= %.0f" , roll, pitch, yaw);
}
int main(int argc,char *argv[])
{setlocale(LC_ALL,"");ros::init(argc, argv,"imu_node" );ros::NodeHandle n;ros::Subscriber imu_sub = n.subscribe( "/imu/data" ,10,IMUCallback);ros::spin( );return 0;
}
ctrl+s快捷保存
3.5 设置C++编译规则
打开CMake文件
add_executable(imu_node src/imu_node.cpp)
add dependencies(imu_node ${${PROJECT_NAVE}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(imu_node${catkin_LIBRARIES}
)
ctrl+s快捷保存

ctrl+shift+b快捷编译
3.6 编译运行imu_node节点
编译,打开终端
cd ~/catkin_ws/
catkin_make
采用wpr_simulation开源工程,打开三个终端分别运行三条指令
roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun imu_pkg imu_node

拖动机器人绕z轴正方向旋转90度


可参照可以打开wpr_simulation里src文件夹下的demo_imu_data.cpp文件,对照一下代码,排查错误

4. 用python获取IMU 数据节点
4.1 通用IMU姿态数据格式

直接获取IMU融合好的机器人姿态四元数
4.2 构思功能的思路和步骤
构思

实现步骤
- 构建一个新的软件包,包名叫做imu_pkg。
- 在软件包中新建一个节点,节点名叫做imu_node.py。
- 在节点中,向ROS大管家rospy申请订阅话题/imu/data,并设置回调函数为imu_callback()。
- 构建回调函数imu_callback(),用来接收和处理IMU数据。
- 使用TF工具将四元数转换成欧拉角。
- 调用loginfo()显示转换后的欧拉角数值。
4.3 创建imu_pkg包
在工作空间src文件创建基于sensor_msgs模板的imu_pkg,编译
cd ~/catkin_ws/src/
catkin_create_pkg imu_pkg roscpp rospy sensor_msgs
cd ..
catkin_make

在imu_pkg文件夹下新建script文件夹中创建imu_node.py

4.4 编写imu_node订阅者节点
先引入python包,设置中文utf-8显示
- ros>=20.04,采用python3
- ros<20.04,采用python
lidar_node.py源码
#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor msgs.msg import Imu
from tf.transformations import euler_from_quaternion
import mathdef imu callback(msg):if msg.orientation covariance[0]< 0:returnquaternion =[msg .orientation.x,msg.orientation.y,msg.orientation.z,msg.orientation.w](roll,pitch , yaw) = euler_from_quaternion(quaternion)roll = roll*180/math.pipitch = pitch*180/math.piyaw = yaw*180/math.pirospy.loginfo(滚转=%.0f俯仰= %.0f朝向= %.of" ,roll,pitch,yaw)if _name ="_main_":rospy.init_node( "imu _node")imu_sub = rospy.subscriber( "/imu/data",Imu,imu_callback,queue_size=10)rospy.spin()
ctrl+s快捷保存
4.5 添加可执行的权限
在所在文件夹打开终端
cd catkin_ws/src/imu_pkg/scripts/
ls
chmod +x imu_node.py
ls
文件名变成绿色表示权限添加成功

4.6 运行imu_node节点
采用wpr_simulation开源工程,打开三个终端分别运行三条指令
roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun vel_pkg vel_node.py



可参照可以打开wpr_simulation里的script文件夹中创建imu_node.py

5. 用C++编写 IMU 航向锁定节点

基于前面学习的机器人运动控制和 IMU 惯性测量单元数据,下面将联系这两点编写 IMU 航向锁定节点,我们可以直接在前面实验的程序上做修改
5.1 构思功能的思路和步骤
- 让大管家NodeHandle 发布速度控制话题/cmd_vel。
- 设定一个目标朝向角,当姿态信息中的朝向角和目标朝向角不一致时,控制机器人转向目标朝向角。
5.2 修改imu_node.cpp

见3.4源码
修改成如下lidar_node源码
#include <ros/ ros.h>
#include <sensor msgs/Imu.h>
#include "tf/tf.h"
#include "geometry msgs/Twist.h"ros::Publisher vel_pub;void IMUCallback(sensor msgs::Imu msg)
{if(msg.orientation_covariance[0] <0)return;tf::Quaternion quaternion(msg.orientation.x,msg.orientation.y,msg.orientation.z,msg.orientation.w);double roll, pitch, yaw;tf::Matrix3x3(quaternion).getRPY( roll, pitch, yaw);roll = roll*180/M_PI;pitch = pitch*180/M_PI;yaw = yaw*180/M_PI;ROS_INFO(“滚转= %.0f 俯仰=%.0f 朝向= %.0f" , roll, pitch, yaw);double target_ yaw = 90;double diff_angle = target_yaw - yaw;geometry_msgS::Twist vel_cmd ;vel_cmd.angular.z = diff_angle * 0.0l;vel_pub.publish(vel_cmd):}
int main(int argc,char *argv[])
{setlocale(LC_ALL,"");ros::init(argc, argv,"imu_node" );ros::NodeHandle n;ros::Subscriber imu_sub = n.subscribe( "/imu/data" ,10,IMUCallback);vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel",10);ros::spin( );return 0;
}
ctrl+s快捷保存
ctrl+shift+b快捷编译

可参照开源项目wpr_simulation下的src文件夹的demo_imu_behavior.cpp

5.4 运行imu_node节点
采用wpr_simulation开源工程,打开三个终端分别运行三条指令
roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun imu_pkg imu_node

拖动机器人绕Z轴旋转,也会自动转回去

5.4 优化航向策略
当机器人检测前方障碍物时,最简单把转弯角度调大一点,原地转弯
imu_node源码
#include <ros/ ros.h>
#include <sensor msgs/Imu.h>
#include "tf/tf.h"
#include "geometry msgs/Twist.h"ros::Publisher vel_pub;void IMUCallback(sensor msgs::Imu msg)
{if(msg.orientation_covariance[0] <0)return;tf::Quaternion quaternion(msg.orientation.x,msg.orientation.y,msg.orientation.z,msg.orientation.w);double roll, pitch, yaw;tf::Matrix3x3(quaternion).getRPY( roll, pitch, yaw);roll = roll*180/M_PI;pitch = pitch*180/M_PI;yaw = yaw*180/M_PI;ROS_INFO(“滚转= %.0f 俯仰=%.0f 朝向= %.0f" , roll, pitch, yaw);double target_ yaw = 90;double diff_angle = target_yaw - yaw;geometr_msgS::Twist vel_cmd ;vel_cmd.angular.z = diff_angle * 0.0l;vel_cmd.linear.x=0.1;vel_pub.publish(vel_cmd):}
int main(int argc,char *argv[])
{setlocale(LC_ALL,"");ros::init(argc, argv,"imu_node" );ros::NodeHandle n;ros::Subscriber imu_sub = n.subscribe( "/imu/data" ,10,IMUCallback);vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel",10);ros::spin( );return 0;
}
ctrl+s快捷保存
ctrl+shift+b快捷编译
采用wpr_simulation开源工程,打开三个终端分别运行三条指令
roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun imu_pkg imu_node

6. 用python编写 IMU 航向锁定节点

基于前面学习的机器人运动控制和 IMU 惯性测量单元数据,下面将联系这两点编写 IMU 航向锁定节点,我们可以直接在前面实验的程序上做修改
6.1 构思功能的思路和步骤
构思

实现步骤
- 让大管家NodeHandle 发布速度控制话题/cmd_vel。
- 设定一个目标朝向角,当姿态信息中的朝向角和目标朝向角不一致时,控制机器人转向目标朝向角。
6.2 修改imu_node.py
打开4.4编写imu_node.py

修改imu_node.py源码
#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor msgs.msg import Imu
from tf.transformations import euler_from_quaternion
import math
from geometry msgs.msg import Twistdef imu callback(msg):if msg.orientation covariance[0]< 0:returnquaternion =[msg .orientation.x,msg.orientation.y,msg.orientation.z,msg.orientation.w](roll,pitch , yaw) = euler_from_quaternion(quaternion)roll = roll*180/math.pipitch = pitch*180/math.piyaw = yaw*180/math.pirospy.loginfo(滚转=%.0f俯仰= %.0f朝向= %.of" ,roll,pitch,yaw)target_yaw = 90diff_angle = target yaw - yawvel_cmd = Twist()vel_cmd.angular.z = diff_angle * 0.01global vel_pubvel_pub.publish(vel_cmd)if _name ="_main_":rospy.init_node( "imu _node")imu_sub = rospy.subscriber( "/imu/data",Imu,imu_callback,queue_size=10)vel_pub = rospy.Publisher( "/cmd_vel",Twist,queue_size=10)rospy.spin()
ctrl+s快捷保存
6.3 运行imu_node节点
采用wpr_simulation开源工程,打开三个终端分别运行三条指令
roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun imu_pkg imu_node.py


6.4 优化航向策略
修改imu_node.py源码
#!/usr/bin/env python3
#coding=utf-8
import rospy
from sensor msgs.msg import Imu
from tf.transformations import euler_from_quaternion
import math
from geometry msgs.msg import Twistdef imu callback(msg):if msg.orientation covariance[0]< 0:returnquaternion =[msg .orientation.x,msg.orientation.y,msg.orientation.z,msg.orientation.w](roll,pitch , yaw) = euler_from_quaternion(quaternion)roll = roll*180/math.pipitch = pitch*180/math.piyaw = yaw*180/math.pirospy.loginfo(滚转=%.0f俯仰= %.0f朝向= %.of" ,roll,pitch,yaw)target_yaw = 90diff_angle = target yaw - yawvel_cmd = Twist()vel_cmd.angular.z = diff_angle * 0.01vel_cmd.linear.x = 0.1global vel_pubvel_pub.publish(vel_cmd)if _name ="_main_":rospy.init_node( "imu _node")imu_sub = rospy.subscriber( "/imu/data",Imu,imu_callback,queue_size=10)vel_pub = rospy.Publisher( "/cmd_vel",Twist,queue_size=10)rospy.spin()
ctrl+s快捷保存
采用wpr_simulation开源工程,打开三个终端分别运行三条指令
roscore
roslaunch wpr_simulation wpb_simple.launch
rosrun imu_pkg imu_node.py

可参照可以打开wpr_simulation里的script文件夹中demo_imu_behavior.py

7. 总结
本节学习了ROS机器人的IMU 惯性测量单元,尝试C++和python两种语言编写获取机器人姿态信息,并且结合前面的机器人运动编写了航向锁定节点,接下来会介绍机器人的更精彩的操作,期待你的关注。🎉🎉🎉
相关文章:
【7. ROS 中的 IMU 惯性测量单元消息包】
欢迎大家阅读2345VOR的博客【6. 激光雷达接入ROS】🥳🥳🥳 2345VOR鹏鹏主页: 已获得CSDN《嵌入式领域优质创作者》称号👻👻👻,座右铭:脚踏实地,仰望星空&#…...
pcie m.2固态硬盘装机后无法识别到启动盘
1、第一种情况《系统版本过低》 原因: 使用m.2固态硬盘的电脑,最好安装iwn8.1以上的系统,因为win7系统及其win xp系统 没有自带NVME驱动。 搞定办法: 比较简单的方式就是直接开运行快启动u盘启动盘制作工具将系统升级到win10系…...
Java Web应用开发 ——第四章:JavaBean技术测验
一.单项选择题(共13题,55.9分) 1 在 JSP 中调用 JavaBean 时不会用到的标记是:( ) A、 < jsp:javabean> B、 < jsp:useBean> C、 < jsp:setProperty> D、 < jsp:getProperty> 正确答案&a…...
CTF权威指南 笔记 -第二章二进制文件- 2.4 -动态链接
目录 静态文件的缺点 动态链接 位置无关代码 延迟绑定 _dl_runtime_reslove 函数定义 深入审视 静态文件的缺点 随着可执行文件的增加 静态链接带来的浪费空间问题就会愈发严重 如果大部分可执行文件都需要glibc 那么在链接的时候就需要把 libc.a链接进去 如果一个libc…...
C++:计算机操作系统:多线程:高并发中的线程
高并发中的线程 一切要从CPU说起PC 程序计数器从CPU到操作系统从进程到线程 从这篇开始,我将会开启高性能,高并发系列,本篇是给系列的开篇,主要关注 多线程以及线程池。 一切要从CPU说起 你可能会有疑问,讲多线程为何…...
大数据Doris(十一):Aggregate 数据模型
文章目录 Aggregate 数据模型 一、导入数据聚合 二、保留明细数据...
osg::Drawable类通过setDrawCallback函数设置回调函数的说明
osg::Drawable类可以通过该类的setDrawCallback函数设置回调函数类对象。被设置的回调类对象必须从osg::Drawable::DrawCallback类派生,并重写drawImplementation函数,以实现自己特定的需求。这个回调函数在每次帧事件中都会被调用(如:在帧的…...
Python基础合集 练习17(类与对象)
class Dog: pass papiDog() print(papi) print(type(papi)) 构建方法 创建类过后可以定义一个特殊的方法。在python中构建方法是__init__(),init()必须包含一个self参数 class pig(): #def__init__(self) -> None: print(‘你好’) pipgpig() 属性和方法 cl…...
再多猜一次就爆炸(小黑子误入)
目录 猜数字游戏 游戏设计思路 1.电脑随机生成一个数 2.猜数字 3.输入我是ikun,泰裤辣! 否则电脑将在一分钟后关机 游戏运行效果 源码 代码分析 代码实现关键语句 strcmp() rand()与srand() 时间戳time() 寄语 猜数字游戏 游戏设计思路 1.电脑随机生…...
图像超分辨率简单介绍
文章目录 图像超分辨率简单介绍什么是图像超分辨率?常见的图像超分辨率算法插值算法基于边缘的图像重建算法局部线性嵌入(LLE)拉普拉斯正则化 基于深度学习的超分辨率算法超分辨率CNN超分辨率GAN 步骤1. 收集数据2. 选择算法3. 训练模型4. 测…...
【Liunx】进程的程序替换——自定义编写极简版shell
目录 进程程序替换[1~5]1.程序替换的接口(加载器)2.什么是程序替换?3.进程替换的原理4.引入多进程5.系列程序替换接口的详细解析(重点!) 自定义编写一个极简版shell[6~8]6.完成命令行提示符7.获取输入的命令…...
c++标准模板(STL)(std::array)(三)
定义于头文件 <array> template< class T, std::size_t N > struct array;(C11 起 std::array 是封装固定大小数组的容器。 此容器是一个聚合类型,其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数组…...
c#笔记-创建一个项目
创建一个项目 创建控制台程序 在你安装完成Visual Studio后打开它,你会的到一个启动窗口 点击创建新项目,选择右上角c#的没有Framework的控制台应用。 项目名称,位置自己随意。 目标框架选择NET7.0。 项目创建完成后应该你的界面应该类似…...
Photoshop如何使用图像调色之实例演示?
文章目录 0.引言1.将一张偏冷调的图像调整成暖调2.将图像调整成不同季节色彩倾向3.变换花朵的颜色4.创建人像轮廓风景5.修饰蓝天白云6.调换花草颜色 0.引言 因科研等多场景需要进行绘图处理,笔者对PS进行了学习,本文通过《Photoshop2021入门教程》及其配…...
IDEA中使用Git提交代码提示:您即将把CRLF行分隔符提交到Gt仓库。 建议将core.autocrlf Git特性设置为trUe,以免发生行分隔符问题。
IDEA中使用Git提交代码提示:您即将把CRLF行分隔符提交到Gt仓库。 建议将core.autocrlf Git特性设置为trUe,以免发生行分隔符问题。 问题背景: 在IDEA中,使用Git提交代码到远程仓库时,结果弹出一个警告窗口 问题原因: …...
ArduPilot之开源代码LibrarySketches设计
ArduPilot之开源代码Library&Sketches设计 1. 简介1.1 Core libraries1.2 Sensor libraries1.3 Other libraries 2. 源由3. Library Sketches设计3.1 设计框架3.2 Example Sketches3.3 AP_Common Sketches3.3.1 配置sitl环境3.3.2 编译AP_Common3.3.3 运行AP_Common3.3.4 代…...
第一章:概述
1,因特网概述 1.网络、互联网和英特网 网络(Network)由若干结点(Node)和连接这些结点的链路(Link)组成。 多个网络还可以通过路由器互连起来,这样就构成了一个覆盖范围更大的网络,即互联网(或互连网)。因此,互联网是“网络的网络…...
MySQL --- DDL图形化工具表结构操作
一. 图形化工具 1. 介绍 前面我们讲解了DDL中关于数据库操作的SQL语句,在我们编写这些SQL时,都是在命令行当中完成的。大家在练习的时候应该也感受到了,在命令行当中来敲这些SQL语句很不方便,主要的原因有以下 3 点:…...
归一化处理(2023寒假每日一题 14)
在机器学习中,对数据进行归一化处理是一种常用的技术。 将数据从各种各样分布调整为平均值为 0 0 0、方差为 1 1 1 的标准分布,在很多情况下都可以有效地加速模型的训练。 这里假定需要处理的数据为 n n n 个整数 a 1 , a 2 , ⋯ , a n a_1,a_2,⋯…...
无公网IP,外网远程连接MySQL数据库
哈喽~大家好,这篇来看看无公网IP,外网远程连接MySQL数据库。 文章目录 前言1. 检查mysql安装状态2. 安装配置cpolar内网穿透3. 创建tcp隧道,映射3306端口4. 公网远程连接4.1 图形化界面4.2 使用命令行远程连接 5. 配置固定tcp端口地址5.1 保留…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
