揭秘全向轮运动学:机动艺术与上下位机通信的智慧桥梁

✨✨ Rqtz 个人主页 : 点击✨✨

🌈Qt系列专栏:点击

🎈Qt智能车上位机专栏: 点击🎈

        本篇文章介绍的是有关于全向轮运动学分析,单片机与上位机通信C++代码以及ROS里程计解算的内容。

目录

大纲

 ROS(机器人操作系统)

全向轮运动学分析

a,b,c三轮

a轮       

c轮

全向轮正运动解算公式(顺时针为正方向)

全向轮逆运动解算公式

矩阵形式

单片机与上位机通信

通信协议的设定(共9位)

上位机发送,下位机解析(将线速度序列化转换为编码器脉冲)

举例说明:

下位机发送,上位机解析(将编码器脉冲反序列化转换为线速度)

为什么说高8位大于等于128就为负数,

线速度到轮子编码器数值(转速)的转化系数

里程计速度解算

公式总结


大纲

全向轮运动学结算主要涉及到:

  • 各个轮子的速度解算
  • 顺逆时针各个轮子和速度公式
  • 速度正交分解示意图

单片机与上位机通信主要涉及到:

  • 如何将解算后的轮子转速转换为编码器数值并按照设定通信协议发送下位机
  • 如何接收下位机反馈编码器数值并转化为轮子转速
  • 涉及上位机发送与接收通信协议以及数值解编码

里程计解算主要是涉及到:

  • 根据轮子转速和imu偏航角度得到机器人在x,y轴行使距离
  • 结合ROS机器人操作系统发布里程计数据

文章最后附公式总结

 ROS(机器人操作系统)

        ROS(机器人操作系统,Robot Operating System),是专为机器人软件开发所设计出来的一套电脑操作系统架构。本文的运动学分解将结合ROS机器人操作系统进行进一步的应用。

全向轮运动学分析

        全向轮(Omni-wheels)以其独特的运动能力和灵活性,成为了众多研究者和技术爱好者关注的焦点。不同于传统的轮式移动系统,全向轮能够在水平面上实现任意方向的平滑移动,无需改变轮子的方向或进行复杂的转向操作。这种革命性的移动方式不仅极大地拓宽了机器人的应用范围,也为自动化、物流、服务机器人等领域带来了前所未有的可能性。

        图一为90度转轴驱动,图二为电机直接驱动。

a,b,c三轮

        全向轮a,b,c三个轮子的线速度分别为Va,Vb,Vc,机器人底盘整体的x轴线速度为Vx,整体的y轴线速度为Vy(以ros中的坐标系为准),机器人底盘逆时针旋转的角速度为w,轮子距离底盘中心的距离为L。其中,轮子与水平线的夹角为120度

        以顺时针方向为正方向。

a轮       

      1.  对于a轮来讲,按照图中顺时针的正方向,将机器人整体x轴线速度与y轴线速度正交分解,以Vx为例,将其分解到沿轮子方向Vx2垂直于轮子方向Vx1;以Vy为例,将其分解到沿轮子方向Vy2和垂直于轮子方向Vy1

         按照图中顺时针的正方向,a轮的和速度为Vx2+Vy2。在根据夹角60度,可得到a轮的线速度公式(机器人底盘逆时针旋转时):

        其中,由图可知,\Theta 1为30度,\Theta 2为60度。\omega L由V =\omega L得到, 由于机器人底盘逆时针旋转圆周运动在a轮的切向速度与轮子正方向相反,所以为负的\omega L

Fxy1 = Vx\cos \Theta 1+Vy\sin \Theta 1-\omega L

Fxy1 = Vx\sqrt{3}/2+Vy1/2-\omega L

       2. a轮的线速度公式(机器人底盘顺时针旋转时):

Fxy1 = Vx\cos \Theta 1+Vy\sin \Theta 1+\omega L

Fxy1 = Vx\sqrt{3}/2+Vy1/2+\omega L

b轮

同理可得

b轮的线速度公式(机器人底盘逆时针旋转时)

Fxy2 = -Vx\sin \Theta 1+Vy\cos \theta 1-\omega L

Fxy2 = -Vx\sqrt{3}/2+Vy1/2-\omega L

b轮的线速度公式(机器人底盘顺时针旋转时)

Fxy2 = -Vx\sin \Theta 1+Vy\cos \theta 1+\omega L

Fxy2 = -Vx\sqrt{3}/2+Vy1/2+\omega L

b轮中图的\theta 1为60度。

c轮

c轮的线速度公式(机器人底盘逆时针旋转时):

Fxy3=-Vy-\omega L

c轮的线速度公式(机器人底盘顺时针旋转时):

Fxy3=-Vy+\omega L

全向轮正运动解算公式(顺时针为正方向)

根据ros的标准坐标系(右手定则),在ros中速度大小都是向前,向左为正,逆时针旋转为正,所以结合ros的标准坐标系,为-wL,得出以下公式:

\begin{bmatrix} Va=Vx\sqrt{3}/2+Vy1/2-\omega L\\ Vb=-Vx\sqrt{3}/2+Vy1/2-\omega L\\ Vc=-Vy-\omega L \end{bmatrix}

全向轮逆运动解算公式

本质为解三元一次方程组,求解Vx,Vy,\omega

\begin{bmatrix} Vx = (Va-Vb)/\sqrt{3}\\ Vy=(Va+Vb-2Vc)/3)\\ \omega = -(Va+Vb+Vc)/(3L) \end{bmatrix}

矩阵形式

\begin{bmatrix} \sqrt{3}/2 & 1/2& -L\\ -\sqrt{3}/2 & 1/2& -L\\ 0& -1&-L \end{bmatrix}   \begin{bmatrix} Vx\\ Vy\\ \omega \end{bmatrix}   =   \begin{bmatrix} Va\\ Vb\\ Vc \end{bmatrix}

根据ros速度回调函数的线角速度分解轮子编码器数值函数:

/*目标速度回调函数*/
void cmd_velCB(const geometry_msgs::Twist & msg)
{  
    target_Vx = msg.linear.x;
    target_Vy = msg.linear.y; 
    target_Vz = msg.angular.z;

    // ROS_INFO("x %lf",target_Vx);
    // ROS_INFO("y %lf",target_Vy);
    // ROS_INFO("z %lf",target_Vz);
    
    //逆时针旋转
    target_Va =  target_Vx*K1 + target_Vy*0.5 - L*target_Vz;
    target_Vb =  -target_Vx*K1 + target_Vy*0.5 - L*target_Vz;
    target_Vc =               - target_Vy     - L*target_Vz; 
    //线速度转换为各轮子转速
    target_a = k_master*target_Va;
    target_b = k_master*target_Vb;
    target_c = k_master*target_Vc;
    // printf("Va=%dfm/s, Vb=%dfm/s, Vc=%dfm/s \n",target_a,target_b,target_c);

    /*发送小车数据到下位机*/
    send_Data();
}

单片机与上位机通信

通信协议的设定(共9位)

  • 包头:0xFF 0xFE
  • a,b,c三个电机各两位(高八位/低八位)[][] [][], [][] [][], [][] [][]
  • 异或校验位 [][]Va=0.4*\sqrt{3}/2+0+0 = 0.4*0.866 \approx 0.35

上位机发送,下位机解析(将线速度序列化转换为编码器脉冲)


        上位机(ros)发送线速度Vx,Vy,Vz——>三个轮子线速度Va,Vb,Vc——>转换到编码器脉冲数(16位数据)Na,Nb,Nc——>再取高八位,低八位Na1,Na2;Nb1,Nb2;Nc1,Nc2


其中用有符号的16位数据来存储三个轮子的编码器的脉冲数,数值的正负来表示电机的正转反转,但取过高低八位的数据是无符号的。

发送小车数据到下位机函数实现

/*发送小车数据到下位机*/
void send_Data()
{
    //发送标志位
    s_buffer[0] = 0xFF;
    s_buffer[1] = 0xFE;   
    //A电机速度
    s_buffer[2] = target_a>>8;//取高八位
    s_buffer[3] = target_a&0x00ff;//取低八
    //B电机速度
    s_buffer[4] = target_b>>8;
    s_buffer[5] = target_b&0x00ff;
    //C电机速度
    s_buffer[6] = target_c>>8;
    s_buffer[7] = target_c&0x00ff;
    //异或校验位(2-7位校验)
    unsigned char check_num =0;
    for(int i=2;i<8;i++)
    {
        check_num ^= s_buffer[i];
        // printf(" %d ",s_buffer[i]);
    }

    s_buffer[8]=check_num;
    //发送9位数据
    my_serial.write(s_buffer,9);
}

如何将一个16位数据取到高低八位:

取到高八位方法:右移八位(>>8)

取到低八位方法:与上0x00ff(&0x00ff)

举例说明:

若上位机(ros)发送仅有Vx = 0.4m/s的x轴线速度,Vy = 0,\omega = 0.

(1).带入前面提到的正运动学公式得到a,b,c轮子的线速度:

Va=0.4\ast \sqrt{3}/2+0+0 \approx 0.35   

Vb=-0.4\ast \sqrt{3}/2+0+0 \approx -0.35

Vc = 0

(2).由轮子线速度得到编码器数值

线速度到轮子编码器数值(转速)的转化系数为 k = 320/\pi/0.152(下方有解释)

相乘即可

Na=0.35\ast(320/\pi /0.152) = 233

Nb=-0.35\ast(320/\pi /0.152) = -233

Nc=0

(3).分别取到高八位,低八位

        Na = 233,233为正数,10进制233转为二进制(233 = 128+64+32+8+1)——>1110 1001(8位)——>转为16位 0000 0000 1110 1001

高八位:0000 0000 1110 1001 右移8位 >>8 得到 0000 0000 ——>0 A电机高8位

低八位:0000 0000 1110 1001 与上0x00ff(&0x00ff) 得到 1110 1001 ——>233 A电机低8位


        Nb = -233,-233为负数(需要转为补码的形式),-233的绝对值233转为二进制——>0000 0000 1110 1001 ——>取反加1 得到1111 1111 0001 0111

高八位:1111 1111 0001 0111右移8位 >>8 得到 1111 1111 ——>255 B电机高8位

低八位:1111 1111 0001 0111 与上0x00ff(&0x00ff) 得到 0001 01111 ——>23 B电机低8位

        因此得到一个结论是:如果有一个电机的的高8位为255(或者大于等于128),就为负数,那么该电机一定是在反转


下位机发送,上位机解析(将编码器脉冲反序列化转换为线速度)

由上述可知,上位机向下位机发送了一帧数据

0xFF 0xFE 00 233 255 23 00 00 校验位,如果下位机反馈回来的数据同样也是

0xFF 0xFE 00 233 255 23 00 00 ,那么我们如何将这一帧数据算回机器人底盘的线速度Vx,Vy与角速度Vz呢?

解答:

        首先判断数据是正数还是负数,判断方法为看最高位(符号位)是0还是1,是0在则为正数,是1则为负数。

        对于A电机的两位 00 233,高8位的最高位为0,则为正数,所以还原后的A电机的编码器脉冲数为0*256+233*1 = 233。(高8位乘以256,低8位乘以1的原因是:16位的数据拆分为高8位,低8位,高8位基数为2^8=256,低8位基数2^0=1。)

        对于B电机的两位 255 23,高8位1111 1111 最高位为1,所以为负数,负数以补码的形式存在,高8位取反0000 0000 ,低8位取反加1,23二进制0001 0111 取反 1110 1000 加1后 1110 1001 转为二进制后为233,因为是负数,所以加个负号为-233。

        对于c电机为0.

所以反序列化后的编码器数值

Na = 233 Nc = -233 Nc = 0

        再得到轮子的线速度,当时发给下位机的时候乘以的是那个转化系数,这时候接收下位机转换后得除以那个转化系数(320/\pi/0.152)。

Va = 233 / (320/\pi/0.152) = 0.35

Vb = -233 / (320/\pi/0.152) = -0.35

Vc = 0

带入前面提到的逆运动学公式得到底盘整体的Vx,Vy,Vz线速度:

Vx = (Va-Vb)/\sqrt{3} = 0.4  

Vy=0

Vz =0

和上位机发送的一摸一样。

上位机解码下位机数据的代码实现:

/*右移七位,判断第一位符号位0是否为1,是的话就是负数*/
if(r_buffer[0]>>7==1){
/*补码转原码后减一*/
r_buffer[0]=~r_buffer[0];
r_buffer[1]=~(r_buffer[1]-0x01);
real_Va = -(r_buffer[0]*256+r_buffer[1])/ k;
 // printf("a电机反转");
 }
else real_Va = (r_buffer[0]*256+r_buffer[1])/ k;                        
                            
if(r_buffer[2]>>7==1){
r_buffer[2]=~r_buffer[2];
r_buffer[3]=~(r_buffer[3]-0x01);
real_Vb = -(r_buffer[2]*256+r_buffer[3])/ k;
//  printf("b电机反转");
}  
else real_Vb = (r_buffer[2]*256+r_buffer[3])/ k;
if(r_buffer[4]>>7==1){
r_buffer[4]=~r_buffer[4];
r_buffer[5]=~(r_buffer[5]-0x01);
real_Vc = -(r_buffer[4]*256+r_buffer[5])/ k;
}
else real_Vc = (r_buffer[4]*256+r_buffer[5])/ k;

为什么说高8位大于等于128就为负数,

为什么说高8位大于等于128就为负数,因为对于一个int16位数据,他的数据总数位2^16 = 65535,又因为是有符号的,所以正数和负数各占一半,最大正整数为32767,最小负整数为-32767.

        32767——>二进制0111 1111 1111 1111(最高位为0,高八位数值为127(64+32+16+8+4+2+1))

        -32767——>绝对值的二进制0111 1111 1111 1111——>取反1000 0000 0000 0000——>加1——>1000 0000 0000 0001(最高位符号位为1,高八位数值为128)

        所以说高八位128是正数与负数的连接处,也是电机正转与反转的连接处。

总结公式

若高八位最高位符号位为0,即正数时

Va = (Na1*256+Na2*1)/K

若高八位最高位符号位为1,即负数时

Va =( -[\sim Na1*256+\sim (Na2-0x01)])/K

Na1为高8位,Na2为低8位,~为取反,k值为编码器数值到车轮线速度的转化系数。

线速度到轮子编码器数值(转速)的转化系数

车轮线速度到编码器数值公式推算

设车轮直径L,编码器CPR 为N,采样周期为T,单周期下编码器反馈计数值为n,车轮线速度为v

显然单周期T时间下车轮行进距离s = v*T

又:s =π*L * n/N

v = [π*L /( T*N ) ]*n

本车中L = 0.152m,编码器CPR = 32000,采样周期为10ms = 0.01s

∴ v = [π*0.152/( 0.01*32000 ) ]*n= (π*0.152/320)*n

里程计速度解算

如图

底盘向左偏移了yaw个弧度,将Vx和Vy分解到X_dis和y_dis坐标轴上得到

x = Vx\ast \cos(yaw)-Vy\ast \sin (yaw)

y = Vx\ast \sin(yaw)+Vy\ast \cos (yaw)

在接收下位机的循环中,获取时间

current_time = ros::Time::now();//获得当前时间
double dt = (current_time - last_time).toSec();//转换成秒
last_time = current_time;

计算里程计数据公式(累加)

x += (Vx\ast \cos(yaw)-Vy\ast \sin (yaw))\ast dt

y += (Vx\ast \sin(yaw)+Vy\ast \cos (yaw))\ast dt

在ros中发布里程计数据

        //里程计累计x行驶距离
        X_dist += (real_Vx*cos(Yaw)-real_Vy*sin(Yaw))*dt;
        //里程计累计y行驶距离
        Y_dist += (real_Vx*sin(Yaw)+real_Vy*cos(Yaw))*dt; 

        //四元数变量
        geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(Yaw);        
        
        //定义里程计对象
        nav_msgs::Odometry odom;
        //载入里程计时间戳
        odom.header.stamp = current_time; 
        //里程计的父子坐标系
        odom.header.frame_id = "odom";
        odom.child_frame_id = "base_link";       
        //里程计位置数据:x,y,z,方向
        odom.pose.pose.position.x = X_dist;     
        odom.pose.pose.position.y = Y_dist;
        odom.pose.pose.position.z = 0.0;
        odom.pose.pose.orientation = odom_quat;       
        //载入线速度和角速度
        odom.twist.twist.linear.x = real_Vx;
        odom.twist.twist.linear.y = real_Vy;
        odom.twist.twist.angular.z = real_Vz;
        if(!real_Vx || !real_Vy || !real_Vz){
            odom.pose.covariance = {1e-9, 0, 0, 0, 0, 0,       
				                0, 1e-3, 1e-9, 0, 0, 0,
				                0, 0, 1e6, 0, 0, 0,
				                0, 0, 0, 1e6, 0, 0,
				                0, 0, 0, 0, 1e6, 0,
				                0, 0, 0, 0, 0, 1e-9};

		    odom.twist.covariance = {1e-9, 0, 0, 0, 0, 0,      
						        0, 1e-3, 1e-9, 0, 0, 0,
						        0, 0, 1e6, 0, 0, 0,
						        0, 0, 0, 1e6, 0, 0,
						        0, 0, 0, 0, 1e6, 0,
						        0, 0, 0, 0, 0, 1e-9};
		    
        }
        else{
           odom.pose.covariance = {1e-3, 0, 0, 0, 0, 0,       
						        0, 1e-3, 0, 0, 0, 0,
						        0, 0, 1e6, 0, 0, 0,
						        0, 0, 0, 1e6, 0, 0,
						        0, 0, 0, 0, 1e6, 0,
						        0, 0, 0, 0, 0, 1e3};

		    odom.twist.covariance = {1e-3, 0, 0, 0, 0, 0,      
						        0, 1e-3, 0, 0, 0, 0,
						        0, 0, 1e6, 0, 0, 0,
						        0, 0, 0, 1e6, 0, 0,
						        0, 0, 0, 0, 1e6, 0,
						        0, 0, 0, 0, 0, 1e3};
		 
        }

其中odom_quat指的是根据偏航角yaw来获取四元数数据,并放入odom里程计的话题类型中。

公式总结

ROS标准坐标系下全向轮正运动解

\begin{bmatrix} Va=Vx\sqrt{3}/2+Vy1/2-\omega L\\ Vb=-Vx\sqrt{3}/2+Vy1/2-\omega L\\ Vc=-Vy-\omega L \end{bmatrix}

ROS标准坐标系下全向轮逆运动解

\begin{bmatrix} Vx = (Va-Vb)/\sqrt{3}\\ Vy=(Va+Vb-2Vc)/3)\\ \omega = -(Va+Vb+Vc)/(3L) \end{bmatrix}

ROS标准坐标系下全向轮正运动解(矩阵形式)

\begin{bmatrix} \sqrt{3}/2 & 1/2& -L\\ -\sqrt{3}/2 & 1/2& -L\\ 0& -1&-L \end{bmatrix}   \begin{bmatrix} Vx\\ Vy\\ \omega \end{bmatrix}   =   \begin{bmatrix} Va\\ Vb\\ Vc \end{bmatrix}

轮子二进制编码器数据解码到轮子线速度

若高八位Na1最高位符号位为0,即正数时

Va = (Na1*256+Na2*1)/K

若高八位Na1最高位符号位为1,即负数时,~为取反

Va =( -[\sim Na1*256+\sim (Na2-0x01)])/K

K为线速度到轮子编码器数值(转速)的转化系数

ROS标准坐标系下里程计运动(累加)解算

x += (Vx\ast \cos(yaw)-Vy\ast \sin (yaw))\ast dt

y += (Vx\ast \sin(yaw)+Vy\ast \cos (yaw))\ast dt

上述内容如果有误,请及时指正批评,谢谢大家!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《AI在企业战略中的关键地位:以微软和阿里为例》

内容概要 在当今商业环境中&#xff0c;人工智能&#xff08;AI&#xff09;的影响力如滔滔洪水&#xff0c;愈演愈烈。文章将揭示AI在企业战略中的崛起&#xff0c;尤其以微软和阿里巴巴为代表的企业&#xff0c;这两家科技巨头通过不同方式&#xff0c;将智能技术融入其核心…

Pandas | 理性判断数据是否存在缺失值的一种方法

理性判断 一般思路进一步思考df[B].explode() 一般思路 tcc.info()上述信息info显示没有缺失值 但是真实的情况还是要根据业务实际分析tcc.isnull().sum() # 和tcc.info()作用和tcc.info() 其实是一样的 进一步思考 在此过程中&#xff0c;我们需要检验是否存在采用别的值来表…

大数据新视界 -- 大数据大厂之经典案例解析:广告公司 Impala 优化的成功之道(下)(10/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

基于vue框架的的冷链食品物流信息管理系统v81wb(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,司机,冷链食品,冷链食品订单,冷链车辆,配送信息,订单费用,站点信息,食品种类,省,市,食品质量,县 开题报告内容 基于Vue框架的冷链食品物流信息管理系统开题报告 一、研究背景与意义 随着全球食品贸易的快速发展和消费者对食品品质…

职场逆袭!学会管理上司,你也能成为职场赢家

书友们&#xff0c;不要错过了&#xff01;我挖到了一本真正让我彻夜难眠的小说&#xff0c;情节跌宕起伏&#xff0c;角色鲜活得就像从书里跳出来陪你聊天。每一页都是新的惊喜&#xff0c;绝对让你欲罢不能。要是你也在寻找那种让人上瘾的阅读体验&#xff0c;这本书就是你的…

byte加byte居然是int了?

问题现象 最近在看 Java 的基础知识时看到一个有意思的现象&#xff0c;在 Java 中两个 byte 相加之后的结果的类型变成 int 类型了&#xff1a; byte a 1; byte b 2; b a b;从Idea给的提示可以看到&#xff0c;两个 byte 类型相加的结果变成了 int 类型&#xff0c;不能…

vue3中使用mqtt数据传输(封装)

使用版本 "mqtt": "^5.8.0",安装指令 npm install mqtt --save ------ yarn add mqtt介绍mqtt 参考使用文档 配置 connection: {protocol: "ws",host: "broker.emqx.io",port: 8083,endpoint: "/mqtt",clean: true,con…

全面解析谷歌浏览器的功能与使用技巧

谷歌浏览器&#xff08;Google Chrome&#xff09;作为全球最受欢迎的网页浏览器之一&#xff0c;以其简洁的界面、快速的加载速度和强大的功能赢得了广大用户的青睐。本文将全面解析谷歌浏览器的功能和使用技巧&#xff0c;帮助您更好地利用这一工具提升上网体验。&#xff08…

《探索Zynq MPSoC》学习笔记(二)

引言&#xff1a;本文开始学习第二章内容&#xff0c;本文重点介绍FPGA、Zynq和Zynq MPSoC器件技术演进以及Zynq和Zynq MPSoC器件的基本结构和特点。 第二章 FPGA、Zynq和Zynq MPSoC &#xff08;1&#xff09; Zynq MPSoC是Xilinx发布的第一款SoC Zynq-7000片上系统&#xf…

mac 本地docker-mysql主从复制部署

mac 本地docker-mysql主从复制部署,服务器同理 1.本地docker启动两个mysql服务.端口号不一样 没有选择挂载到宿主机.只做测试用. 只是端口号不一样容器删掉.就没有数据了. 生产测试,需要挂在 master docker run -d --name mysql-slave -p 3308:3306 \ -e MYSQL_ROOT_PASSWORD…

七.numpy模块

NumPy(Numerical Python) 是 Python 语言的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库。 NumPy 的前身 Numeric 最早是由 Jim Hugunin 与其它协作者共同开发&#xff0c;2005 年&#xff0c;Travis Oliphant…

测试用例小锦囊——基于思维导图的测试用例生成和维护

敲黑板&#xff0c;测试用例真的很重要&#xff01; 测试用例是测试工作的基础&#xff0c;通过提供结构化和系统化的方法&#xff0c;来帮助验证软件产品的功能是否按预期正确实现&#xff0c;从而确保软件质量&#xff0c;提升用户满意度。 测试用例的关键要素包括用例编号、…

Linux网络命令:用于查看和修改路由表的重要工具ip route 详解

目录 一、概述 二、用法 1、基本语法 2、参数说明 3、常用选项 4、获取帮助 三、基本用法示例 1、 查看路由表 2、 添加路由 3、 删除路由 4、 修改路由 5、 添加默认路由 6、 删除默认路由 四、路由表管理 1、查看所有路由表 2、指定路由表 五、其他选项 1、…

银行信贷风控专题:Python、R 语言机器学习数据挖掘应用实例合集:xgboost、决策树、随机森林、贝叶斯等

银行信贷风控专题&#xff1a;Python、R 语言机器学习数据挖掘应用实例合集&#xff1a;xgboost、决策树、随机森林、贝叶斯等 原创 拓端研究室 全文链接&#xff1a;https://tecdat.cn/?p38026 在当今金融领域&#xff0c;风险管控至关重要。无论是汽车贷款违约预测、银行挖掘…

容器内pip安装Apache Airflow的经历:如何重置初始密码

背景 Apache Airflow™https://github.com/apache/airflow 是一个开源平台&#xff0c;用于开发、调度和监控面向批处理的工作流程。Airflow 可扩展的 Python 框架使您能够构建几乎可以连接任何技术的工作流程。Web 界面有助于管理工作流程的状态。Airflow 可以通过多种方式部…

RHCE作业四

一要求&#xff1a; 1.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 2.配置从DNS服务器&#xff0c;对主dns服务器进行数据备份。 二操作&#xff1a; 主服务器 1.安装 2主配置真反向 3正反设置 区域 1安装 2添加allow-transfer 3增量 4重启 Systemctl …

算法练习:1658. 将 x 减到 0 的最小操作数

题目链接&#xff1a;1658. 将 x 减到 0 的最小操作数 这道题目的意思就是&#xff0c;给定一个整数数组&#xff0c;和一个x&#xff0c;只能从数组最左边或者最右边进行删除&#xff0c;使得x恰好等于0&#xff0c;并且要操作次数最少的情况&#xff0c;否则返回-1. 这道题直…

职场如雷场,稍有不慎就会被炸翻?十大生存法则送给你

大多数人的一生都要经历过&#xff1a;求学&#xff0c;入职&#xff0c;退休三个阶段。其中职场生涯一般都在30至40年左右&#xff0c;占据了人生的大部分时间&#xff0c;而这段时间&#xff0c;是每个人最年富力强&#xff0c;精力充沛的时光。 那么&#xff0c;如何把这人…

这款神器,运维绝杀 !!!

项目简介 CrowdSec 是一款开源的、基于社区协作的网络安全防护工具&#xff0c;它通过分析和共享IP信誉数据来对抗恶意行为。该软件不仅支持IPv6&#xff0c;而且相较于传统的Python实现&#xff0c;其采用Go语言编写&#xff0c;运行速度提升了60倍。CrowdSec 利用Grok模式解析…

[C++] cpphttplib使用https而不是http

前言 首先我们假设是直接使用 httplib.h 的源文件。 支持 https 根据readme来看&#xff0c;需要开启一个宏&#xff0c;链接libssl和libcrypto就可以了。 下载openssl 保姆级OpenSSL下载及安装教程 选择非light的版本&#xff0c;这样才会有头文件和lib库引入文件。 编写C…