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

四轮转向轮式里程计设计(python)

目录

  • 写在前面的话
  • 参考教程
    • 官方教程
    • 参考代码(c++)
  • 关键代码解析
    • 订阅车轮速度
    • 订阅车轮转向
    • 订阅四轮转向控制模式
    • 积累速度和转向角
    • 发布里程计
  • 完整代码
  • 完整视频演示

写在前面的话

上一篇博客:键盘控制车子四轮转向

这篇文章通过订阅车轮的速度和转向计算得到整车的速度和转向,同时发布轮式里程计信息,需要和 四轮转向键盘控制改进版 ros2(python) 进行配套使用

大部分的车子的底盘控制器其实不需要自己写轮式里程计,因为ros2有很多官方的底盘控制器,比如两轮差速等常见底盘控制器,这些官方底盘控制器会自带轮式里程计。本文用的不是官方的四轮转向底盘,所以需要再写一个轮式里程计。(耗时1-2个星期)

参考教程

官方教程

1 里程计设置
2 Publishing Odometry Information over ROS

参考代码(c++)

Autonomous-Ackerman-Simulation/four_ws_navigation/four_wheel_steering_controller/src

在这里插入图片描述

关键代码解析

订阅车轮速度

订阅话题/forward_velocity_controller/commands,回调函数self.velocity_callback

self.wheel_v_sub = self.create_subscription(Float64MultiArray, '/forward_velocity_controller/commands', self.velocity_callback, 10)def velocity_callback(self, msg):# 处理 '/forward_velocity_controller/commands' 话题的消息# self.get_logger().info('Received data from /forward_velocity_controller/commands: %s' % list(msg.data))self.wheel_v_array = list(msg.data)

订阅车轮转向

订阅话题/forward_position_controller/commands,回调函数self.position_callback

self.wheel_w_sub = self.create_subscription(Float64MultiArray, '/forward_position_controller/commands', self.position_callback, 10)def position_callback(self, msg):# 处理 '/forward_position_controller/commands' 话题的消息# self.get_logger().info('Received data from /forward_position_controller/commands: %s' % list(msg.data))self.wheel_w_array = list(msg.data)

订阅四轮转向控制模式

订阅话题/keyboard_control_mode,回调函数self.control_mode_callback

self.mode_sub = self.create_subscription(Int32, '/keyboard_control_mode', self.control_mode_callback, 10)def control_mode_callback(self, msg):# 处理 '/control_4ws_mode 话题的消息# self.get_logger().info('Received data from /control_4ws_mode: %s' % msg.data)self.control_mode = msg.data

积累速度和转向角

self.current_time = self.get_clock().now()
dt = (self.current_time - self.last_time).nanoseconds / 1e9self.vx, self.vy, self.vth = self.forward_kinematics(self.control_mode, self.wheel_v_array, self.wheel_w_array)
self.get_logger().info(f'\n self.x:{self.x}, self.y:{self.y}, self.th:{self.th}, dt:{dt}')
self.get_logger().info(f'\n self.vx:{self.vx}, self.vy:{self.vy}, self.vth:{self.vth}')
#====================== publish odom ====================#delta_x = (self.vx * math.cos(self.th) - self.vy * math.sin(self.th))*dt
delta_y = (self.vx * math.sin(self.th) + self.vy * math.cos(self.th))*dt
delta_th = self.vth*dtself.th += delta_th
self.x += delta_x
self.y += delta_y# self.get_logger().info(f'\n self.x:{self.x}, self.y:{self.y}, self.th:{self.th}')
self.last_time = self.current_time

发布里程计

self.odom_pub = self.create_publisher(Odometry, '/odom', 50)
self.odom_broadcaster = TransformBroadcaster(self)odom_quat = Quaternion()
# magnitude = math.sqrt(odom_quat.x**2 + odom_quat.y**2 
#                       + math.sin(self.th / 2)**2 + math.cos(self.th / 2)**2)# 归一化四元数
# odom_quat.z /= magnitude
# odom_quat.w /= magnitudeodom_quat.z = math.sin(self.th / 2)
odom_quat.w = math.cos(self.th / 2)# Publish the transform
odom_trans = TransformStamped()
odom_trans.header.stamp = self.current_time.to_msg()
odom_trans.header.frame_id = 'odom'
odom_trans.child_frame_id = 'base_link'
odom_trans.transform.translation.x = self.x
odom_trans.transform.translation.y = self.y
odom_trans.transform.translation.z = 0.0
odom_trans.transform.rotation = odom_quatself.odom_broadcaster.sendTransform(odom_trans)# Publish the odometry message
odom = Odometry()
odom.header.stamp = self.current_time.to_msg()
odom.header.frame_id = 'odom'
odom.pose.pose.position.x = self.x
odom.pose.pose.position.y = self.y
odom.pose.pose.position.z = 0.0
odom.pose.pose.orientation = odom_quat
odom.child_frame_id = 'base_link'
odom.twist.twist.linear = Vector3(x=self.vx, y=self.vy, z=0.0)
odom.twist.twist.angular = Vector3(x=0.0, y=0.0, z=self.vth)
self.odom_pub.publish(odom)

完整代码

Class Commdar(Node) 通过整车速度和转向控制车轮速度和车轮转向
Class OdometryPublisher(Node) forward_kinematics 函数通过车轮速度和车轮转向计算整车速度和转向

#!/usr/bin/python3
import math
import threading
import rclpy
import numpy as np
from rclpy.node import Node
from std_msgs.msg import Float64MultiArray
from geometry_msgs.msg import Twist
from sensor_msgs.msg import Joy
import sys, select, termios, tty
from nav_msgs.msg import Odometry
import pty
from geometry_msgs.msg import Quaternion, TransformStamped, Twist, Vector3
from nav_msgs.msg import Odometry
from tf2_ros import TransformBroadcaster
from tf2_ros import TransformStamped
import math
from std_msgs.msg import Int32class Commander(Node):'''wheel_separation:Shortest distance between the left and right wheels. If this parameter is wrong, the robot will not behave correctly in curves.wheel_base:Distance between front and rear wheels, in meters.wheel_radius:Radius of a wheel, i.e., wheels size, used for transformation of linear velocity into wheel rotations. If this parameter is wrong the robot will move faster or slower then expected.'''def __init__(self):super().__init__('commander')self.wheel_seperation = 1.2self.wheel_base = 1self.wheel_radius = 0.3self.wheel_steering_y_offset = 0.03self.steering_track = self.wheel_seperation - 2*self.wheel_steering_y_offset #1.14self.pos = np.array([0,0,0,0], float)self.vel = np.array([0,0,0,0], float) #left_front, right_front, left_rear, right_rearself.pub_pos = self.create_publisher(Float64MultiArray, '/forward_position_controller/commands', 10)self.pub_vel = self.create_publisher(Float64MultiArray, '/forward_velocity_controller/commands', 10)self.sub_vel = self.create_subscription(Twist,'/keyboard_vel_msg', self.vel_callback, 10)self.sub_mode = self.create_subscription(Int32, '/keyboard_control_mode', self.mode_callback, 10)self.sub_velself.sub_modeself.vel_msg = Twist()self.vel_msg.linear.x = 0.0self.vel_msg.linear.y = 0.0self.vel_msg.angular.x = 0.0 self.vel_msg.angular.y = 0.0 self.vel_msg.angular.z = 0.0self.control_mode = Int32()self.control_mode.data = 1self.create_timer(timer_period_sec=0.02, callback=self.timer_callback)def vel_callback(self, msg):self.vel_msg = msgreturndef mode_callback(self, msg):self.control_mode = msg.datareturn def timer_callback(self):vel_msg = self.vel_msgmode_selection = self.control_mode# opposite phaseif(mode_selection == 1):vel_steerring_offset = vel_msg.angular.z * self.wheel_steering_y_offset / self.wheel_radiussign = math.copysign(1.0, vel_msg.linear.x)            self.vel[0] = sign*math.hypot(vel_msg.linear.x - vel_msg.angular.z*self.steering_track/2, vel_msg.angular.z*self.wheel_base/2)/self.wheel_radius - vel_steerring_offsetself.vel[1] = sign*math.hypot(vel_msg.linear.x + vel_msg.angular.z*self.steering_track/2, vel_msg.angular.z*self.wheel_base/2)/self.wheel_radius + vel_steerring_offsetself.vel[2] = sign*math.hypot(vel_msg.linear.x - vel_msg.angular.z*self.steering_track/2, vel_msg.angular.z*self.wheel_base/2)/self.wheel_radius - vel_steerring_offsetself.vel[3] = sign*math.hypot(vel_msg.linear.x + vel_msg.angular.z*self.steering_track/2, vel_msg.angular.z*self.wheel_base/2)/self.wheel_radius + vel_steerring_offsetif abs(2.0 * vel_msg.linear.x) > abs(vel_msg.angular.z * self.steering_track) and math.fabs(vel_msg.linear.y) < 0.001:front_left_steering = math.atan(vel_msg.angular.z * self.wheel_base / (2.0 * vel_msg.linear.x - vel_msg.angular.z * self.steering_track))front_right_steering = math.atan(vel_msg.angular.z * self.wheel_base / (2.0 * vel_msg.linear.x + vel_msg.angular.z * self.steering_track))self.pos[0] = front_left_steeringself.pos[1] = front_right_steeringelif abs(vel_msg.linear.x) > 0.001 and math.fabs(vel_msg.linear.y) < 0.001:front_left_steering = math.copysign(math.pi / 2, vel_msg.angular.z)front_right_steering = math.copysign(math.pi / 2, vel_msg.angular.z)self.pos[0] = front_left_steeringself.pos[1] = front_right_steering# self.pos[0] = math.atan(vel_msg.angular.z*self.wheel_base/(2*vel_msg.linear.x + vel_msg.angular.z*self.steering_track+0.001))# self.pos[1] = math.atan(vel_msg.angular.z*self.wheel_base/(2*vel_msg.linear.x - vel_msg.angular.z*self.steering_track+0.001))self.pos[2] = -self.pos[0]self.pos[3] = -self.pos[1]# in-phaseelif(mode_selection == 2):V = math.hypot(vel_msg.linear.x, vel_msg.linear.y)sign = np.sign(vel_msg.linear.x)if(vel_msg.linear.x != 0):ang = vel_msg.linear.y / vel_msg.linear.xelse:ang = 0self.pos[0] = math.atan(ang)self.pos[1] = math.atan(ang)self.pos[2] = self.pos[0]self.pos[3] = self.pos[1]self.vel[:] = sign*V            # pivot turnelif(mode_selection == 3):omega_const = 6  # to make robot rotates a little bit slowerself.pos[0] = -math.atan(self.wheel_base/self.steering_track)self.pos[1] = math.atan(self.wheel_base/self.steering_track)self.pos[2] = math.atan(self.wheel_base/self.steering_track)self.pos[3] = -math.atan(self.wheel_base/self.steering_track)self.vel[0] = -vel_msg.angular.z/(omega_const * self.wheel_radius)self.vel[1] = vel_msg.angular.z/(omega_const * self.wheel_radius)self.vel[2] = self.vel[0]self.vel[3] = self.vel[1]else:self.pos[:] = 0self.vel[:] = 0# fixed by xcg: change the sign of the positionself.pos = -self.pospos_array = Float64MultiArray(data=self.pos) vel_array = Float64MultiArray(data=self.vel) self.pub_pos.publish(pos_array)self.pub_vel.publish(vel_array)self.pos[:] = 0self.vel[:] = 0class OdometryPublisher(Node):def __init__(self):super().__init__('odometry_publisher')self.wheel_v_sub = self.create_subscription(Float64MultiArray, '/forward_velocity_controller/commands', self.velocity_callback, 10)self.wheel_w_sub = self.create_subscription(Float64MultiArray, '/forward_position_controller/commands', self.position_callback, 10)self.mode_sub = self.create_subscription(Int32, '/keyboard_control_mode', self.control_mode_callback, 10)self.wheel_v_sub  # 防止被 GC 回收self.wheel_w_subself.mode_subself.odom_pub = self.create_publisher(Odometry, '/odom', 50)self.odom_broadcaster = TransformBroadcaster(self)self.get_logger().info('Subscribed to /forward_velocity(position)_controller/commands topic')self.x = 0.0self.y = 0.0self.th = 0.0self.vx = 0.0self.vy = 0.0self.vth = 0.0self.wheel_base_ = 1.0 self.wheel_seperation = 1.2self.steering_track_ = 1.14self.wheel_steering_y_offset_ = 0.03self.wheel_radius_ = 0.3 #轮子半径30cmself.wheel_v_array = [0,0,0,0]self.wheel_w_array = [0,0,0,0]self.control_mode = 1self.current_time = self.get_clock().now()self.last_time = self.get_clock().now()timer_period = 0.1self.timer = self.create_timer(timer_period, self.timer_callback)def velocity_callback(self, msg):# 处理 '/forward_velocity_controller/commands' 话题的消息# self.get_logger().info('Received data from /forward_velocity_controller/commands: %s' % list(msg.data))self.wheel_v_array = list(msg.data)def position_callback(self, msg):# 处理 '/forward_position_controller/commands' 话题的消息# self.get_logger().info('Received data from /forward_position_controller/commands: %s' % list(msg.data))self.wheel_w_array = list(msg.data)def control_mode_callback(self, msg):# 处理 '/control_4ws_mode 话题的消息# self.get_logger().info('Received data from /control_4ws_mode: %s' % msg.data)self.control_mode = msg.datadef forward_kinematics(self, control_mode, wheel_velocity, wheel_angular):# transform wheel_velocity and wheel_angular to the whole carfl_speed = wheel_velocity[0]#车轮线速度,没除车轮半径fr_speed = wheel_velocity[1]rl_speed = wheel_velocity[2]rr_speed = wheel_velocity[3]fl_steering = wheel_angular[0]#轮子转角fr_steering = wheel_angular[1]rl_steering = wheel_angular[2]rr_steering = wheel_angular[3]# 检查转向角是否为 NaNif any(math.isnan(steering) for steering in [fl_steering, fr_steering, rl_steering, rr_steering]):return# 计算前轮转向位置front_steering = 0.0if abs(fl_steering) > 0.001 or abs(fr_steering) > 0.001:# self.get_logger().info(f'\n fl_steering:{fl_steering}, math.tan(fl_steering):{math.tan(fl_steering)}, fr_steering:{fr_steering}')if control_mode != 3:front_steering = math.atan(2 * math.tan(fl_steering) * math.tan(fr_steering) / (math.tan(fl_steering) + math.tan(fr_steering))#pivot模式下正负为0)else:front_steering = 0.0# 计算后轮转向位置rear_steering = 0.0if abs(rl_steering) > 0.001 or abs(rr_steering) > 0.001:if control_mode != 3:rear_steering = math.atan(2 * math.tan(rl_steering) * math.tan(rr_steering) / (math.tan(rl_steering) + math.tan(rr_steering)))else:rear_steering = 0.0front_tmp = math.cos(front_steering) * (math.tan(front_steering) - math.tan(rear_steering)) / self.wheel_base_front_left_tmp = front_tmp / math.sqrt(1 - self.steering_track_ * front_tmp * math.cos(front_steering)+ (self.steering_track_ * front_tmp / 2)**2)front_right_tmp = front_tmp / math.sqrt(1 + self.steering_track_ * front_tmp * math.cos(front_steering)+ (self.steering_track_ * front_tmp / 2)**2)fl_speed_tmp = fl_speed * (1 / (1 - self.wheel_steering_y_offset_ * front_left_tmp))fr_speed_tmp = fr_speed * (1 / (1 - self.wheel_steering_y_offset_ * front_right_tmp))front_linear_speed = self.wheel_radius_ * math.copysign(1.0, fl_speed_tmp + fr_speed_tmp) * math.sqrt((fl_speed**2 + fr_speed**2) / (2 + (self.steering_track_ * front_tmp)**2 / 2.0))rear_tmp = math.cos(rear_steering) * (math.tan(front_steering) - math.tan(rear_steering)) / self.wheel_base_rear_left_tmp = rear_tmp / math.sqrt(1 - self.steering_track_ * rear_tmp * math.cos(rear_steering)+ (self.steering_track_ * rear_tmp / 2)**2)rear_right_tmp = rear_tmp / math.sqrt(1 + self.steering_track_ * rear_tmp * math.cos(rear_steering)+ (self.steering_track_ * rear_tmp / 2)**2)rl_speed_tmp = rl_speed * (1 / (1 - self.wheel_steering_y_offset_ * rear_left_tmp))rr_speed_tmp = rr_speed * (1 / (1 - self.wheel_steering_y_offset_ * rear_right_tmp))rear_linear_speed = self.wheel_radius_ * math.copysign(1.0, rl_speed_tmp + rr_speed_tmp) * math.sqrt((rl_speed_tmp**2 + rr_speed_tmp**2) / (2 + (self.steering_track_ * rear_tmp)**2 / 2.0))if fl_speed == 0:return 0.0, 0.0, 0.0if control_mode == 1:#opposite phaseself.angular_ = (front_linear_speed * front_tmp + rear_linear_speed * rear_tmp) / 2.0self.linear_x_ = (front_linear_speed * math.cos(front_steering) + rear_linear_speed * math.cos(rear_steering)) / 2.0self.linear_y_ = (front_linear_speed * math.sin(front_steering) - self.wheel_base_ * self.angular_ / 2.0 +rear_linear_speed * math.sin(rear_steering) + self.wheel_base_ * self.angular_ / 2.0) / 2.0# print('opposite phase mode...')elif control_mode == 2:#in-phasec_sign = math.copysign(1.0, rl_speed)self.linear_x_ = c_sign * math.sqrt(fl_speed**2 / (1 + math.tan(fl_steering)**2))self.linear_y_ = math.tan(fl_steering) * self.linear_x_self.angular_ = 0.0print('in-phase mode...')elif control_mode == 3:self.linear_x_ = 0.0self.linear_y_ = 0.0R = math.sqrt((self.wheel_base_ / 2) ** 2 + (self.steering_track_ / 2) ** 2) + self.wheel_steering_y_offset_self.angular_ = - self.wheel_radius_ * fl_speed / Rprint('pivot turn mode...')else:self.linear_x_ = 0.0self.linear_y_ = 0.0self.angular_ = 0.0print('other mode...')# print('\nn调用函数了马???')self.get_logger().info(f'\n self.linear_x_:{self.linear_x_}, self.linear_y_:{self.linear_y_}, self.angular_:{self.angular_}, control_mode:{control_mode}')return self.linear_x_, self.linear_y_, self.angular_def timer_callback(self):self.current_time = self.get_clock().now()dt = (self.current_time - self.last_time).nanoseconds / 1e9self.vx, self.vy, self.vth = self.forward_kinematics(self.control_mode, self.wheel_v_array, self.wheel_w_array)self.get_logger().info(f'\n self.x:{self.x}, self.y:{self.y}, self.th:{self.th}, dt:{dt}')self.get_logger().info(f'\n self.vx:{self.vx}, self.vy:{self.vy}, self.vth:{self.vth}')#====================== publish odom ====================#delta_x = (self.vx * math.cos(self.th) - self.vy * math.sin(self.th))*dtdelta_y = (self.vx * math.sin(self.th) + self.vy * math.cos(self.th))*dtdelta_th = self.vth*dtself.th += delta_thself.x += delta_xself.y += delta_y# self.get_logger().info(f'\n self.x:{self.x}, self.y:{self.y}, self.th:{self.th}')self.last_time = self.current_timeodom_quat = Quaternion()# magnitude = math.sqrt(odom_quat.x**2 + odom_quat.y**2 #                       + math.sin(self.th / 2)**2 + math.cos(self.th / 2)**2)# 归一化四元数# odom_quat.z /= magnitude# odom_quat.w /= magnitudeodom_quat.z = math.sin(self.th / 2)odom_quat.w = math.cos(self.th / 2)# Publish the transformodom_trans = TransformStamped()odom_trans.header.stamp = self.current_time.to_msg()odom_trans.header.frame_id = 'odom'odom_trans.child_frame_id = 'base_link'odom_trans.transform.translation.x = self.xodom_trans.transform.translation.y = self.yodom_trans.transform.translation.z = 0.0odom_trans.transform.rotation = odom_quatself.odom_broadcaster.sendTransform(odom_trans)# Publish the odometry messageodom = Odometry()odom.header.stamp = self.current_time.to_msg()odom.header.frame_id = 'odom'odom.pose.pose.position.x = self.xodom.pose.pose.position.y = self.yodom.pose.pose.position.z = 0.0odom.pose.pose.orientation = odom_quatodom.child_frame_id = 'base_link'odom.twist.twist.linear = Vector3(x=self.vx, y=self.vy, z=0.0)odom.twist.twist.angular = Vector3(x=0.0, y=0.0, z=self.vth)self.odom_pub.publish(odom)class Joy_subscriber(Node):def __init__(self):super().__init__('joy_subscriber')self.subscription = self.create_subscription(Joy,'joy',self.listener_callback,10)self.subscriptiondef listener_callback(self, data):global vel_msg, mode_selectionif(data.buttons[0] == 1):   # in-phase # A button of Xbox 360 controllermode_selection = 2elif(data.buttons[4] == 1): # opposite phase # LB button of Xbox 360 controllermode_selection = 1elif(data.buttons[5] == 1): # pivot turn # RB button of Xbox 360 controllermode_selection = 3else:mode_selection = 4vel_msg.linear.x = data.axes[1]*7.5vel_msg.linear.y = data.axes[0]*7.5vel_msg.angular.z = data.axes[3]*10if __name__ == '__main__':rclpy.init(args=sys.argv)commander = Commander()#需要, 缺少无法发布odom话题# joy_subscriber = Joy_subscriber()odom_pub = OdometryPublisher()executor = rclpy.executors.MultiThreadedExecutor()executor.add_node(commander)executor.add_node(odom_pub)# executor.add_node(joy_subscriber)executor_thread = threading.Thread(target=executor.spin, daemon=True)executor_thread.start()rate = commander.create_rate(2)try:while rclpy.ok():rate.sleep()except KeyboardInterrupt:passrclpy.shutdown()executor_thread.join()

完整视频演示

在这里插入图片描述

四轮转向轮式里程计设计 G果-CSDN

相关文章:

四轮转向轮式里程计设计(python)

目录 写在前面的话参考教程官方教程参考代码&#xff08;c&#xff09; 关键代码解析订阅车轮速度订阅车轮转向订阅四轮转向控制模式积累速度和转向角发布里程计 完整代码完整视频演示 写在前面的话 上一篇博客&#xff1a;键盘控制车子四轮转向 这篇文章通过订阅车轮的速度和…...

多方法做配对样本t检验(三)

Wilcoxon符号秩检验 Wilcoxon符号秩检验&#xff08;Wilcoxon Signed-Rank Test&#xff09; 是一种非参数统计方法&#xff0c;用于检验两组相关样本&#xff08;配对样本&#xff09;之间的差异是否显著。它通常用来代替配对样本t检验&#xff0c;特别是在数据不符合正态分布…...

Vue 将推出「无虚拟DOM」版本,又是新的前端框架趋势?

文章目录 背景无虚拟DOM版的Vue3Vue Vapor 在线演练题外话&#xff1a;渲染流程 背景 随着 React 和 Vue 这些前端框架的爆火&#xff0c;他们的渲染方式&#xff0c;虚拟DOM&#xff0c;也跟着火了起来&#xff0c;大家都认为这是一种高性能批量更新DOM的方式但是近一两年有不…...

阿里云ECS服务器磁盘空间不足的几个文件

查看磁盘空间命令&#xff1a; df -h /mnt 清零 echo >nohup.out 磁盘空间不足的文件列表&#xff1a; 一、nohup.out&#xff1a;来自"nohup java -jar service.jar &"命令产生的文件&#xff0c;位置在服务jar所在目录 二、access.log&#xff1a;位于…...

从0开始linux(38)——线程(1)线程概念

欢迎来到博主专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 进程与线程线程概念线程的优点线程的独立数据 进程与线程 如果要理解线程&#xff0c;那么进程将会时绕不开的点。首先我们回顾一下我们之前在进程章节当中是如何描述进程的&#xff1f; 进程&…...

Ubuntu源码安装gitlab13.7集群多前端《二》

Ubuntu源码安装gitlab13.7《一》 gitaly需要调整的服务 redis socket->ipbind ....* # 0.0.0.0pg vim /etc/postgresql/14/main/pg_hba.confhost all all ..../32 md5gitaly vim /home/git/gitaly/config.tomlbin_dir "/home/gi…...

身份证OCR 识别 API 接口的发展前景

随着信息时代的到来&#xff0c;大量的身份证数据需要进行整理、存储和管理&#xff0c;OCR 识别技术可以将身份证信息转化为结构化的电子文本&#xff0c;方便后续的数据管理和分析&#xff0c;提高工作效率。 未来&#xff0c;随着人工智能和深度学习等技术的不断发展&#…...

Spring boot之BeanDefinition介绍

在spring框架中IOC容器进行bean的创建和管理。Bean的创建是一个比较复杂的过程&#xff0c;它并不像我们创建对象一样只是直接new一下就行&#xff0c;虽然有些bean确实就是New一下。但在Spring中可以通过一些途径对bean进行增强扩展。在这个过程中&#xff0c;BeanDefinition作…...

30分钟学会正则表达式

正则表达式是对字符串操作的一种逻辑公式&#xff0c;就是用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个“规则字符串”&#xff0c;这个“规则字符串”用来表达对字符串的一种过滤逻辑。 作用 匹配 查看一个字符串是否符合正则表达式的语法 搜索 正…...

Python 自动化办公的 10 大脚本

大家好&#xff0c;我是你们的 Python 讲师&#xff01;今天我们将讨论 10 个实用的 Python 自动化办公脚本。这些脚本可以帮助你简化日常工作&#xff0c;提高效率。无论是处理 Excel 文件、发送邮件&#xff0c;还是自动化网页操作&#xff0c;Python 都能派上用场。 1. 批量…...

Python蒙特卡罗MCMC:优化Metropolis-Hastings采样策略Fisher矩阵计算参数推断应用—模拟与真实数据...

全文链接&#xff1a;https://tecdat.cn/?p38397 本文介绍了其在过去几年中的最新开发成果&#xff0c;特别阐述了两种有助于提升 Metropolis - Hastings 采样性能的新要素&#xff1a;跳跃因子的自适应算法以及逆 Fisher 矩阵的计算&#xff0c;该逆 Fisher 矩阵可用作提议密…...

成绩排序

成绩排序 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给出班里某门课程的成绩单&#xff0c;请你按成绩从高到低对成绩单排序输出&#xff0c;如果有相同分数则名字字典序小的在前。 输入 第一行为…...

MySQL底层概述—7.优化原则及慢查询

大纲 1.Explain概述 2.Explain详解 3.索引优化数据准备 4.索引优化原则详解 5.慢查询设置与测试 6.慢查询SQL优化思路 1.Explain概述 使用Explain关键字可以模拟查询优化器来执行SQL查询语句&#xff0c;从而知道MySQL是如何处理SQL语句的&#xff0c;从而分析出查询语句…...

R““有什么作用在C++中,举例说明

在C中&#xff0c;R""&#xff08;双引号前加R&#xff09;表示一个原始字符串字面量&#xff08;Raw String Literal&#xff09;&#xff0c;其主要作用是让字符串中的反斜杠\和其他特殊字符不被当作转义字符处理&#xff0c;而是保留其原始字面意义。这在处理包含…...

linux中top 命令返回数据解释

当您在 Linux 终端中运行 top 命令时,它会显示一个动态更新的系统状态视图,其中包括许多有关系统性能的数据。下面是对 top 命令返回数据的详细解释: 标题栏 top - 22:46:12 up 2 days, 3:14, 1 user, load average: 0.05, 0.07, 0.09 22:46:12:当前时间。up 2 days, 3:14…...

深入理解二叉树及其变体:平衡二叉树、红黑树、B-树和B+树

一、二叉树简介 二叉树是一种非常常见的数据结构&#xff0c;它具有以下特点&#xff1a; 每个节点最多有两个子节点&#xff0c;分别称为左子节点和右子节点。每个节点的左子树和右子树都是二叉树。 二叉树的常见操作包括&#xff1a;创建、插入、删除、查找、遍历等。下面…...

C++ 编程技巧之StrongType(1)

最近看到一个NamedType的开源库&#xff0c;被里面的Strong Type这个概念和里面的模版实现给秀了一脸&#xff0c;特此总结学习一下 GitHub - joboccara/NamedType: Implementation of strong types in C C本身是一种强类型语言&#xff0c;类型包括int、double等这些build i…...

芯片测试-smith圆图

smith圆图 &#x1f4a2;smith圆图的故事&#x1f4a2;&#x1f4a2;smith圆图中的各部分来历&#x1f4a2;&#x1f4a2;公式推导&#x1f4a2;&#x1f4a2;等电阻圆特点&#x1f4a2;&#x1f4a2;等电抗圆&#x1f4a2;&#x1f4a2;等电抗圆特点&#x1f4a2; &#x1f4a…...

HTML技术深度解析:构建现代网页的基石

引言 HTML&#xff08;HyperText Markup Language&#xff0c;超文本标记语言&#xff09;是构建网页和网上应用的标准标记语言。随着互联网技术的飞速发展&#xff0c;HTML已经成为前端开发中不可或缺的核心技术之一。本文将深入探讨HTML的基本概念、核心元素、最新发展以及在…...

Leecode刷题C语言之判断是否可以赢得数字游戏

执行结果:通过 执行用时和内存消耗如下&#xff1a; bool canAliceWin(int* nums, int numsSize) {int single_digit_sum 0;int double_digit_sum 0;for (int i 0; i < numsSize; i) {if (nums[i] < 10) {single_digit_sum nums[i];} else {double_digit_sum nums[…...

Ubuntu 关机命令

在 Ubuntu 系统中&#xff0c;有几种方法可以关机。以下是常用的关机命令及其说明&#xff1a; 1. 使用 shutdown 命令 shutdown 命令是最常用和最灵活的关机方式。它可以设置定时关机&#xff0c;并且可以发送警告消息给所有登录用户。 立即关机 sudo shutdown now定时关机…...

数据采集中,除了IP池的IP被封,还有哪些常见问题?

在数据采集的过程中&#xff0c;代理IP池的使用无疑为我们打开了一扇通往信息宝库的大门。然而&#xff0c;除了IP被封禁这一常见问题外&#xff0c;还有许多其他问题可能影响数据采集的效果。本文将探讨在数据采集中&#xff0c;除了IP被封之外&#xff0c;还可能遇到的一些常…...

【Anaconda】 创建环境报错:CondaHTTPError: HTTP 000 CONNECTION FAILED for url

问题描述 使用 Anaconda 创建环境时报错&#xff1a; CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/free/noarch/repodata.json.bz2> Elapsed: -An HTTP error occurred when trying to retrieve this URL. HTTP errors are o…...

社交电商破局之“2+1 链动模式 O2O 商城小程序源码”赋能流量困境突围

摘要&#xff1a;本文聚焦于当下商家在流量困境中挣扎的现状&#xff0c;剖析传统电商高流量成本、平台流量获取难等痛点&#xff0c;阐述私域流量池兴起的缘由与价值。重点探究“21 链动模式 O2O 商城小程序源码”如何融入社交电商架构&#xff0c;通过创新机制与线上线下融合…...

【ArcGIS Pro微课1000例】0062:ArcGIS Pro3.3.1中文版安装教程(附安装包下载)

本文讲述ArcGIS Pro3.3.1中文版安装教程(附安装包下载)。 文章目录 一、ArcGIS Pro3.3.1中文版下载二、ArcGIS Pro3.3.1中文版安装一、ArcGIS Pro3.3.1中文版下载 【订阅专栏】,获取完整安装包及专栏配套实验数据。下载后解压,如下图所示: 二、ArcGIS Pro3.3.1中文版安装…...

Linux - web服务器

四、web服务器 1、基础知识 URL&#xff1a;Uniform Resource Locator&#xff0c;统一资源定位符&#xff0c;对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示&#xff0c;是互联网上标准资源的地址。 网址格式&#xff1a;<协议>://<主机或主机名&g…...

设计模式-适配器模式-注册器模式

设计模式-适配器模式-注册器模式 适配器模式 如果开发一个搜索中台&#xff0c;需要适配或接入不同的数据源&#xff0c;可能提供的方法参数和平台调用的方法参数不一致&#xff0c;可以使用适配器模式 适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至…...

减速机润滑油更换的最佳周期是多久?

减速机是工业设备中的重要组成部分&#xff0c;润滑油的使用对于其正常运转和寿命具有至关重要的作用。那么&#xff0c;减速机多久更换一次润滑油呢&#xff1f;实际上&#xff0c;减速机润滑油的更换周期受多种因素影响&#xff0c;以下是一些具体的更换周期建议&#xff1a;…...

程序执行堆栈执行模拟

所有的文件都是在硬盘&#xff08;磁盘&#xff09;上&#xff0c;调用时先调用javac指令的jdk编译成.class然后被java指令的jre送到内存中&#xff0c;java在内存中有自己的一片区域叫JVM&#xff0c;编译进来的文件首先进入方法区。 staitc的属性就是在进入内存的时候开辟了一…...

《Python基础》之数据加密模块hashlib的用法

目录 一、简介 二、用法 步骤一、导入hashlib库 步骤二、创建哈希对象 步骤三、往哈希对象中传值 1、可以在创建对象的时候传值 2、使用updata传值 步骤四、获取经过哈希对象加密后的值 三、注意事项 1、编码问题 2、安全性 3、多次传值 四、总结 一、简介 hashli…...

wordpress新用户权限/关键词排名seo优化

随着智能家居技术发展越来越成熟&#xff0c;各种各样的智能家居系统也应运而生。从通信方式的角度去认识智能家居&#xff0c;供您在选购时选择最适合自己需求的技术系统&#xff0c;目前主流的智能家居系统通信方式有&#xff1a;总线、无线、电力载波和以太网。 一、基于总…...

网站营销公司简介/seo排名软件

系列文章目录 Hive3第一章&#xff1a;环境安装 Hive3第二章&#xff1a;简单交互 Hive3第三章&#xff1a;DML数据操作 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、数据导入1. 向表中装载…...

php做动态网站/seo搜索引擎优化技术

SQL Server 数据库启动过程&#xff0c;以及启动不起来的各种问题的分析及解决技巧参考文章&#xff1a; &#xff08;1&#xff09;SQL Server 数据库启动过程&#xff0c;以及启动不起来的各种问题的分析及解决技巧 &#xff08;2&#xff09;https://www.cnblogs.com/VicL…...

wordpress 卸载插件/广东清远今天疫情实时动态防控

目录 冯诺依曼体系 程序(program) 指令(instruction) 数据(data) CPU的基本工作原理 逻辑门&#xff1a;二级的电子开关 非门 与门 或门 异或门 算术逻辑单元 ALU(Arithmetic & Logic Unit) 算术单元(Arithmetic Unit) 逻辑单元(Logic Unit) ALU符号 控制单元 CU(Con…...

广州web网站开发培训班/百度用户服务中心人工24小时电话

小信号分析法重点笔记开关电源的反馈环路设计是开关电源设计的一个非常重要的部分&#xff0c;它关系到一个电源性能的好坏。要设计一个好的环路&#xff0c;必须要知道主回路的数学模型&#xff0c;然后根据主回路的数学模型&#xff0c;设计反馈补偿环路。开关电源是一个非线…...

做一个网站做少多少钱/帮我搜一下长沙做网络销售

本文转自&#xff1a;http://blogs.msdn.com/b/azchina/archive/2010/03/11/windows-azure-table-storage.aspx 本文是Windows Azure入门教学的第六篇文章。 本文将会介绍如何使用Table Storage。Table Storage提供给我们一个云端的表格结构。我们可以把他想象为XML文件或者是一…...