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

二自由度机械臂软件系统(三)ros2_control硬件底层插件

  • ros2_control实现了两个功能,一个是控制算法插件即控制的实现,另一个是底层插件即跟硬件通信的功能。

参考资料:https://zhuanlan.zhihu.com/p/682574842

1、创建功能包

ros2 pkg create --build-type ament_cmake robot_control_test
  • 在src中创建功能包并编译

2、创建launch文件

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.conditions import IfCondition
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitutionfrom launch_ros.actions import Node
from launch_ros.substitutions import FindPackageSharedef generate_launch_description():# Declare arguments 1、声明参数declared_arguments = []declared_arguments.append(DeclareLaunchArgument("description_file",default_value="robottest.urdf.xacro",    #这个名字是跟description中的xacro文件有关的description="URDF/XACRO description file with the robot.带有机器人的URDF/XACRO描述文件。",))declared_arguments.append(DeclareLaunchArgument("gui",default_value="true",description="Start Rviz2 and Joint State Publisher gui automatically \with this launch file.使用此启动文件自动启动Rviz2和Joint State Publisher gui。",))declared_arguments.append(DeclareLaunchArgument("prefix",default_value='""',description="Prefix of the joint names, useful for \multi-robot setup. If changed than also joint names in the controllers' configuration \have to be updated.\关节名称的前缀,用于多机器人设置。如果改变了,那么控制器配置中的联合名称也必须更新",))# Initialize Arguments  2、初始化参数description_file = LaunchConfiguration("description_file")gui = LaunchConfiguration("gui")prefix = LaunchConfiguration("prefix")# Get URDF via xacro   3、通过xacro给出urdfrobot_description_content = Command([PathJoinSubstitution([FindExecutable(name="xacro")])," ",PathJoinSubstitution([FindPackageShare("robot_test_control"), "urdf", description_file]),])robot_description = {"robot_description": robot_description_content}# rviz_config_file = PathJoinSubstitution(#     [FindPackageShare("motor_test_control"), "rviz", "motorbot_view.rviz"]# )########################################################################################joint_state_publisher_node = Node(package="joint_state_publisher_gui",executable="joint_state_publisher_gui",condition=IfCondition(gui),)#发布关节数据信息robot_state_publisher_node = Node(package="robot_state_publisher",executable="robot_state_publisher",output="both",parameters=[robot_description],)#发布模型信息rviz_node = Node(package="rviz2",executable="rviz2",name="rviz2",output="log",# arguments=["-d", rviz_config_file],condition=IfCondition(gui),)#rviz节点nodes = [joint_state_publisher_node,robot_state_publisher_node,rviz_node,]return LaunchDescription(declared_arguments + nodes)
  • 启动文件分成了两部分,参数的存储和节点生成。前面都是在准备所需的参数,后面设置节点,最终利用LaunchDescription生成了节点。
节点名作用
rviz_node运行rviz
joint_state_publisher_node用一个ui获得控制命令,并发布到状态节点
robot_state_publisher_node主要用于发布机器人的urdf模型数据

3、机器人的xacro文件

在这里插入图片描述

(1)robottest.urdf.xacro

<?xml version="1.0"?>
<!-- Basic differential drive mobile base -->
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="robotdrive_robot"><!-- 导入基本的几何形状 --><xacro:include filename="$(find robot_control_test)/urdf/robottest_description.urdf.xacro" /><!-- 导入 ros2_control 描述部分 --><xacro:include filename="$(find robot_control_test)/urdf/robottest.ros2_control.xacro" /></robot>
  • 分别导入模型和控制器

(2)robottest.ros2_control.xacro

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro"><ros2_control name="test_control123" type="system"><hardware><plugin>robot_control_test/RobotTestSystemHardware</plugin></hardware><joint name="link1_joint"><command_interface name="position"/><state_interface name="position"/><state_interface name="velocity"/></joint><joint name="link2_joint"><command_interface name="position"/><state_interface name="position"/><state_interface name="velocity"/></joint></ros2_control></robot>
  • 这是导入控制器的代码,注意在这里引入了底层控制器的插件。这个插件就是之后要写代码编译生成的动态库

4、底层硬件控制器代码

#include "motor_test_system.hpp"#include <chrono>
#include <cmath>
#include <cstddef>
#include <limits>
#include <memory>
#include <vector>#include "hardware_interface/types/hardware_interface_type_values.hpp"
#include "rclcpp/rclcpp.hpp"
#include "utils_can.h"utils_can motor1(1);
utils_can motor2(2);namespace
{
constexpr auto DEFAULT_COMMAND_TOPIC = "motor_test_cmd";
constexpr auto DEFAULT_STATE_TOPIC = "motor_test_state";}  // namespacenamespace motor_test_control
{
hardware_interface::CallbackReturn MotorTestSystemHardware::on_init(const hardware_interface::HardwareInfo & info)
{ std::cout << "初始化" << std::endl;//1、打开can盒int state = 0;state = VCI_OpenDevice(VCI_USBCAN2A,0,0);if(state==1)//打开设备{std::cout << "open deivce success!\n" <<std::endl;//打开设备成功}else if(state==-1){std::cout << "no can device!\n" <<std::endl;}else{printf(">>open deivce fail!\n");//这个就算成功打开,还是为0}//2、初始化两路can口//2.1 can1初始化VCI_INIT_CONFIG config_can;config_can.AccCode=0;config_can.AccMask=0xFFFFFFFF;config_can.Filter=1;//接收所有帧config_can.Mode=0;//正常模式config_can.Timing0=0x00;/*波特率1000 Kbps*/config_can.Timing1=0x14;std::cout <<"1000" <<std::endl;if(VCI_InitCAN(VCI_USBCAN2,0,0,&config_can)!=1){std::cout << ">>Init CAN fail" <<std::endl;VCI_CloseDevice(VCI_USBCAN2,0);}else{std::cout << ">>Init CAN success" <<std::endl;}if(VCI_StartCAN(VCI_USBCAN2,0,0)!=1){VCI_CloseDevice(VCI_USBCAN2,0);}else{std::cout << ">>start CAN success" <<std::endl;}motor1.CanInit();motor2.CanInit();if (hardware_interface::SystemInterface::on_init(info) !=hardware_interface::CallbackReturn::SUCCESS){return hardware_interface::CallbackReturn::ERROR;}if (info_.joints.size() != 2){RCLCPP_FATAL(rclcpp::get_logger("MotorTestSystemHardware"),"The number of crawlers is set not correactly,please check your urdf. 2 is expected,but now it is %zu.", info_.joints.size());return hardware_interface::CallbackReturn::ERROR;}else{RCLCPP_INFO(rclcpp::get_logger("MotorTestSystemHardware"), "Found 2 crawlers sucessfully!");}hw_positions_.resize(info_.joints.size(), std::numeric_limits<double>::quiet_NaN());hw_velocities_.resize(info_.joints.size(), std::numeric_limits<double>::quiet_NaN());hw_commands_.resize(info_.joints.size(), std::numeric_limits<double>::quiet_NaN());for (const hardware_interface::ComponentInfo & joint : info_.joints){// DiffBotSystem has exactly two states and one command interface on each jointif (joint.command_interfaces.size() != 1){RCLCPP_FATAL(rclcpp::get_logger("MotorTestSystemHardware"),"Joint '%s' has %zu command interfaces found. 1 expected.", joint.name.c_str(),joint.command_interfaces.size());return hardware_interface::CallbackReturn::ERROR;}if (joint.command_interfaces[0].name != hardware_interface::HW_IF_POSITION){RCLCPP_FATAL(rclcpp::get_logger("MotorTestSystemHardware"),"Joint '%s' have %s command interfaces found. '%s' expected.", joint.name.c_str(),joint.command_interfaces[0].name.c_str(), hardware_interface::HW_IF_POSITION);return hardware_interface::CallbackReturn::ERROR;}if (joint.state_interfaces.size() != 2){RCLCPP_FATAL(rclcpp::get_logger("MotorTestSystemHardware"),"Joint '%s' has %zu state interface. 2 expected.", joint.name.c_str(),joint.state_interfaces.size());return hardware_interface::CallbackReturn::ERROR;}if (joint.state_interfaces[0].name != hardware_interface::HW_IF_POSITION){RCLCPP_FATAL(rclcpp::get_logger("MotorTestSystemHardware"),"Joint '%s' have '%s' as first state interface. '%s' expected.", joint.name.c_str(),joint.state_interfaces[0].name.c_str(), hardware_interface::HW_IF_POSITION);return hardware_interface::CallbackReturn::ERROR;}if (joint.state_interfaces[1].name != hardware_interface::HW_IF_VELOCITY){RCLCPP_FATAL(rclcpp::get_logger("MotorTestSystemHardware"),"Joint '%s' have '%s' as second state interface. '%s' expected.", joint.name.c_str(),joint.state_interfaces[1].name.c_str(), hardware_interface::HW_IF_VELOCITY);return hardware_interface::CallbackReturn::ERROR;}}return hardware_interface::CallbackReturn::SUCCESS;
}std::vector<hardware_interface::StateInterface> MotorTestSystemHardware::export_state_interfaces()
{std::vector<hardware_interface::StateInterface> state_interfaces;for (auto i = 0u; i < info_.joints.size(); i++){state_interfaces.emplace_back(hardware_interface::StateInterface(info_.joints[i].name, hardware_interface::HW_IF_POSITION, &hw_positions_[i]));state_interfaces.emplace_back(hardware_interface::StateInterface(info_.joints[i].name, hardware_interface::HW_IF_VELOCITY, &hw_velocities_[i]));}return state_interfaces;
}std::vector<hardware_interface::CommandInterface> MotorTestSystemHardware::export_command_interfaces()
{std::vector<hardware_interface::CommandInterface> command_interfaces;for (auto i = 0u; i < info_.joints.size(); i++){command_interfaces.emplace_back(hardware_interface::CommandInterface(info_.joints[i].name, hardware_interface::HW_IF_POSITION, &hw_commands_[i]));}return command_interfaces;
}hardware_interface::CallbackReturn MotorTestSystemHardware::on_activate(const rclcpp_lifecycle::State & /*previous_state*/)
{std::cout << "激活" << std::endl;// BEGIN: This part here is for exemplary purposes - Please do not copy to your production codeRCLCPP_INFO(rclcpp::get_logger("MotorTestSystemHardware"), "Activating ...please wait...");// END: This part here is for exemplary purposes - Please do not copy to your production code// set some default valuesfor (auto i = 0u; i < hw_positions_.size(); i++){if (std::isnan(hw_positions_[i])){hw_positions_[i] = 0;hw_velocities_[i] = 0;hw_commands_[i] = 0;}}subscriber_is_active_ = true;this->node_ =  std::make_shared<rclcpp::Node>("hardware_node");std_msgs::msg::Float64MultiArray empty_int16array;for(std::size_t i = 0; i < hw_positions_.size(); i++){empty_int16array.data.push_back(0.0);}received_fb_msg_ptr_.set(std::make_shared<std_msgs::msg::Float64MultiArray>(empty_int16array));fb_subscriber_ =this->node_->create_subscription<std_msgs::msg::Float64MultiArray>(DEFAULT_STATE_TOPIC, rclcpp::SystemDefaultsQoS(),[this](const std::shared_ptr<std_msgs::msg::Float64MultiArray> msg) -> void{if (!subscriber_is_active_){RCLCPP_WARN(this->node_->get_logger(), "Can't accept new commands. subscriber is inactive");return;}received_fb_msg_ptr_.set(std::move(msg));});//创建实时Publishercmd_publisher = this->node_->create_publisher<std_msgs::msg::Float64MultiArray>(DEFAULT_COMMAND_TOPIC, rclcpp::SystemDefaultsQoS());realtime_cmd_publisher_ = std::make_shared<realtime_tools::RealtimePublisher<std_msgs::msg::Float64MultiArray>>(cmd_publisher);RCLCPP_INFO(rclcpp::get_logger("MotorTestSystemHardware"), "Successfully activated!");return hardware_interface::CallbackReturn::SUCCESS;
}hardware_interface::CallbackReturn MotorTestSystemHardware::on_deactivate(const rclcpp_lifecycle::State & /*previous_state*/)
{std::cout << "反激活" << std::endl;// BEGIN: This part here is for exemplary purposes - Please do not copy to your production codeRCLCPP_INFO(rclcpp::get_logger("MotorTestSystemHardware"), "Deactivating ...please wait...");subscriber_is_active_ = false;fb_subscriber_.reset();received_fb_msg_ptr_.set(nullptr);// END: This part here is for exemplary purposes - Please do not copy to your production codeRCLCPP_INFO(rclcpp::get_logger("MotorTestSystemHardware"), "Successfully deactivated!");return hardware_interface::CallbackReturn::SUCCESS;
}hardware_interface::return_type motor_test_control::MotorTestSystemHardware::read(const rclcpp::Time & /*time*/, const rclcpp::Duration & period)
{std::cout << "读" << std::endl;std::shared_ptr<std_msgs::msg::Float64MultiArray> fb_msg;received_fb_msg_ptr_.get(fb_msg);rclcpp::spin_some(this->node_);for (std::size_t i = 0; i < hw_positions_.size(); i++){// Update the joint status: this is a revolute joint without any limit.double pos_ = 0;int id_ = 0;motor1.receive_callback(pos_,id_);if(id_==1){std::cout << "id==1" << std::endl;
hw_positions_[0] = pos_;}else if(id_==2){std::cout << "id==2" << std::endl;
hw_positions_[1] = pos_;}else{std::cout << "else:" << id_<<std::endl;}if(i < hw_velocities_.size()){hw_velocities_[i] = fb_msg->data[i];// hw_positions_[i] = fb_msg->data[i];//+= period.seconds() * hw_velocities_[i];std::cout << "读:" << hw_positions_[i]<<std::endl;}}return hardware_interface::return_type::OK;
}hardware_interface::return_type motor_test_control::MotorTestSystemHardware::write(const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/)
{std::cout << "写" << std::endl;if(realtime_cmd_publisher_->trylock()){auto & cmd_msg = realtime_cmd_publisher_->msg_;cmd_msg.data.resize(hw_commands_.size());for (auto i = 0u; i < hw_commands_.size(); i++){cmd_msg.data[i] = hw_commands_[i];std::cout << "写:" <<cmd_msg.data[i] <<std::endl;}motor1.send_callback(cmd_msg.data[0]/3.14*180.0);motor2.send_callback(cmd_msg.data[1]/3.14*180.0);realtime_cmd_publisher_->unlockAndPublish();}return hardware_interface::return_type::OK;
}}  // namespace diff_test_control#include "pluginlib/class_list_macros.hpp"
PLUGINLIB_EXPORT_CLASS(motor_test_control::MotorTestSystemHardware, hardware_interface::SystemInterface)

相关文章:

二自由度机械臂软件系统(三)ros2_control硬件底层插件

ros2_control实现了两个功能&#xff0c;一个是控制算法插件即控制的实现&#xff0c;另一个是底层插件即跟硬件通信的功能。 参考资料&#xff1a;https://zhuanlan.zhihu.com/p/682574842 1、创建功能包 ros2 pkg create --build-type ament_cmake robot_control_test在sr…...

24.8.9.11数据结构|链栈和队列

链栈 1、理解 实际上是一个仅在表头进行操作的单链表,头指针指向栈顶结点或头结点,以下恋栈均指带头结点的链栈. 2、 基本操作 1、定义结构&#xff1a;节点含有数据域和指针域 2、初始化操作&#xff1a;建立一个带头结点的空栈 3、取栈顶元素操作&#xff1a;取出栈的栈顶元…...

StarSpider:一款高效的网络爬虫框架解析与实战

文章目录 引言官网链接StarSpider 原理简介基础使用1. 添加依赖2. 编写PageProcessor3. 启动爬虫 高级使用1. 分布式抓取2. 自定义下载器3. 深度定制 优点结语 引言 在大数据时代&#xff0c;数据成为了推动业务增长和创新的关键。网络爬虫作为数据获取的重要手段之一&#xf…...

LVS详细解析及其NAT模式与DR模式部署(理论+实验全方位指导)

目录 1. 集群 2. 分布式系统 3. 集群与分布式的比较 4.通俗的解释 集群 分布式系统 总结 LVS&#xff08;Linux Virtual Server&#xff09;简介 LVS专业术语 工作原理 LVS调度算法 静态调度算法 动态调度算法 ipvsadm脑图 NAT模式集群 LVS的配置 在LVS主机内打开…...

负载均衡相关概念介绍(一)

负载均衡&#xff08;Load Balance&#xff09;是集群技术的一种重要应用&#xff0c;旨在将负载&#xff08;工作任务&#xff09;进行平衡、分摊到多个操作单元上进行运行&#xff0c;从而提高系统的并发处理能力、增加吞吐量、加强网络处理能力&#xff0c;并提供故障转移以…...

二叉树详解(1)

文章目录 目录1. 树的概念及结构1.1 树的相关概念1.2 树的表示1.3 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2. 二叉树的概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的存储结构 3. 二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构…...

Spring定时任务注解

Service EnableScheduling public class xxxServiceImpl implement xxxService{Scheduled(cron "0 15 11 * * ?") // 每天的11:15执行public void reportCurrentTime() {aaa();}Scheduled(cron "0 15 17 * * ?") // 每天的17:15执行public void report…...

数据结构-绪论

学习目标&#xff1a; 认识数据结构的基本内容 学习内容&#xff1a; 了解&#xff1a;数据结构的研究内容掌握&#xff1a;数据结构的基本概念和术语了解&#xff1a;数据元素间的结构关系掌握&#xff1a;算法及算法的描述 数据结构的发展&#xff1a; 数据结构的发展简史 …...

Web开发:web服务器-Nginx的基础介绍(含AI文稿)

目录 一、Nginx的功能&#xff1a; 二、正向代理和反向代理的区别 三、Nginx负载均衡的主要功能 四、nginx安装目录下的各个文件&#xff08;夹&#xff09;的作用&#xff1a; 五、常用命令 一、Nginx的功能&#xff1a; 1.反向代理&#xff1a;例如我有三台服务器&#x…...

共享经济背景下校园、办公闲置物品交易平台-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设残哥 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目、 源…...

Linux 服务器上简单配置 minio

Linux 服务器上简单配置 minio 初始化结构目录 mkdir -p /data/minio/bin mkdir -p /data/minio/conf mkdir -p /data/minio/data 下载 minio cd /data/minio/bin curl -O https://dl.min.io/server/minio/release/linux-amd64/minio 添加执行权限 chmod x minio 创建配置文件…...

TypeScript 面试题汇总

引言 TypeScript 是一种由微软开发的开源、跨平台的编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;为 JavaScript 添加了静态类型系统和其他高级功能。随着 TypeScript 在前端开发领域的广泛应用&#xff0c;掌握 TypeScript 已经成为很多开发者必备的技能之一。本文…...

杰卡德系数

杰卡德系数&#xff08;Jaccard Index 或 Jaccard Similarity Coefficient&#xff09; 杰卡德系数是一种用于衡量两个集合相似度的重要指标。 从数学定义上来看&#xff0c;如前面所述&#xff0c;杰卡德系数计算公式为&#xff1a; J ( A , B ) ∣ A ∩ B ∣ ∣ A ∪ B ∣…...

微服务实现-sleuth+zipkin分布式链路追踪和nacos配置中心

1. sleuthzipkin分布式链路追踪 在大型系统的微服务化构建中&#xff0c;一个系统被拆分成了许多微服务。这些模块负责不同的功能&#xff0c;组合成系统&#xff0c;最终可以提供丰富的功能。 这种架构中&#xff0c;一次请求往往需要涉及到多个服务。互联网应用构建在不同的软…...

数学中常用的解题方法

文章目录 待定系数法应用示例1. 多项式除法2. 分式化简3. 数列通项公式 总结 递归数列特征方程特征根的求解通项公式的求解示例 错位相减&#xff0c;差分错位相减法差分的应用结合理解 韦达定理二项式定理二项式定理的通项公式二项式系数的性质应用示例 一元二次求解1. 因式分…...

pytorch 1 张量

张量 文章目录 张量torch.Tensor 的 主要属性torch.Tensor 的 其他常用属性和方法叶子张量&#xff08;Leaf Tensors&#xff09;定义叶子张量的约定深入理解示例代码总结 中间计算结果与 detach() 方法定义中间计算结果不是叶子节点使用 detach() 方法使中间结果成为叶子张量示…...

音视频开发继续学习

RGA模块 RGA模块定义 RGA模块是RV1126用于2D图像的裁剪、缩放、旋转、镜像、图片叠加等格式转换的模块。比方说&#xff1a;要把一个原分辨率1920 * 1080的视频压缩成1280 * 720的视频&#xff0c;此时就要用到RGA模块了。 RGA模块结构体定义 RGA区域属性结构体 imgType&am…...

【Datawhale X 魔搭 】AI夏令营第四期大模型方向,Task1:智能编程助手(持续更新)

在一个数据驱动的世界里&#xff0c;人工智能的未来应由每一个愿意学习和探索的人共同塑造和掌握。希望这里是你实现AI梦想的起点。 大模型小白入门&#xff1a;https://linklearner.com/activity/14/11/25 大模型开发工程师能力测试&#xff1a;https://linklearner.com/activ…...

如何判断监控设备是否支持语音对讲

目录 一、大华摄像机 二、海康摄像机 三、宇视摄像机 一、大华摄像机 注意&#xff1a;大华摄像机支持跨网语音对讲&#xff0c;即设备和服务器可以不在同一网络内&#xff0c;大华设备的语音通道填写&#xff1a;34020000001370000001 配置接入示例&#xff1a; 音频输入…...

Grafana+Influxdb(Prometheus)+Apache Jmeter搭建可视化性能测试监控平台

此性能测试监控平台&#xff0c;架构可以是&#xff1a; GrafanaInfluxdbJmeterGrafanaPrometheusJmeter Influxdb和Prometheus在这里都是时序性数据库 在测试环境中&#xff0c;压测数据对存储和持久化的要求不高&#xff0c;所以这里的组件可以都通过docker-compose.yml文件…...

【笔记】MSPM0G3507移植RT-Thread——MSPM0G3507与RT_Thread(二)

一.创建新工程 找到"driverlib\empty"空白工程&#xff0c;CTRLC然后CTRLV复制副本 重命名为G3507_RTT 打开KEIL工程 双击empty.syscfg&#xff0c;然后打开SYSCONFIG 我的不知道为啥没有48pin选项&#xff0c;如果你也一样&#xff0c;可以跟着我做&#xff0c;如果…...

计算机毕业设计 美发管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

soapui调用接口参数传递嵌套xml,多层CDATA表达形式验证

1.环境信息 开发工具&#xff1a;idea 接口测试工具&#xff1a;soapui 编程语言&#xff1a;java 项目环境&#xff1a;jdk1.8 webservice&#xff1a;jdk自带的jws 处理xml&#xff1a;jdk自带的jaxb 2.涉及代码 package org.example.webdemo;import javax.jws.WebMethod; i…...

GB/T35561-2017d,GB/T38565-2020,ocr解析文本

因系统需要只找到pdf版本&#xff0c;解析一版记录 GB/T35561-2017d 10000 , 自然灾害 10100 , 水旱灾害 10101 , 洪水 10102 , 内涝 10103 , 水库重大险情 10104 , 堤防重大险情 10105 , 凌汛 10106 , 山洪 10107 , 农业干旱 10108 , 城镇缺水 10109 , 生态干旱 10110 , 农村…...

IDEA使用LiveTemplate快速生成方法注释

本文目标&#xff1a;开发人员&#xff0c;在了解利用Live Template动态获取方法输入输出参数、创建日期时间方法的条件下&#xff0c;进行自动生成方法注释&#xff0c;达到自动添加方法注释的程度&#xff1b; 文章目录 1 场景2 要点2.1 新增LiveTemplate模版2.2 模版内容填写…...

慢SQL优化

1、避免使用select * select * 不会走覆盖索引&#xff0c;会出现大量的回表操作&#xff0c;从而导致查询sql的性能很低。 --反例 select * from user where id 1;--正例 select name,age from user where id 1;2、union all 代替 union union&#xff1a;去重后的数据…...

MES生产执行系统源码,支持 SaaS 多租户,技术架构:springboot + vue-element-plus-admin

MES的定义与功能 MES是制造业中一种重要的管理信息系统&#xff0c;用于协调和监控整个生产过程。它通过收集、分析和处理各种生产数据&#xff0c;实现对生产流程的实时跟踪和监控&#xff0c;并为决策者提供准确的数据支持。MES涵盖了工厂运营、计划排程、质量管理、设备维护…...

【Linux】分析hung_panic生成的vmcore

简介 1、遇到一个问题&#xff1a; 上述日志是oom_kill&#xff0c;下述日志是hung_panic 2、分别解释两层含义&#xff0c;全部日志如下&#xff1a; [75834.243209] kodo invoked oom-killer: gfp_mask0x600040(GFP_NOFS), order0, oom_score_adj968 [75834.245657] CPU: 0…...

unity 画线写字

效果 1.界面设置 2.涉及两个脚本UIDraw.cs和UIDrawLine.cs UIDraw.cs using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI;public class UIDraw : MonoBehaviour, IPointerEnterHandler, IPointerEx…...

GitHub的详细介绍

GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;它建立在Git这个分布式版本控制系统之上&#xff0c;为开发者提供了在云端存储、管理和共享代码的便捷方式。以下是对GitHub的详细介绍&#xff1a; ### 一、GitHub的基本功能 1. **代码托管**&#xff1a;GitHub允…...

合肥市住房和城乡建设局网站/百度推广竞价是什么意思

在MSDN中&#xff0c;.net的数据库连接字符串都有详细的说明&#xff0c;具体的每一项代表的意义可以参看MSDN.ADO.net 中数据库连接方式(微软提供) 微软提供了以下四种数据库连接方式&#xff1a;System.Data.OleDb.OleDbConnectionSystem.Data.SqlClient.SqlConnectionSystem…...

wordpress 会员插件/广州百度竞价外包

Mac OS X - 重置 MySQL Root 密码您是否忘记了Mac OS 的MySQL的root密码? 通过以下4步就可重新设置新密码&#xff1a;1. 停止 mysql server. 通常是在 ‘系统偏好设置‘ > MySQL > ‘Stop MySQL Server‘2. 打开终端&#xff0c;输入&#xff1a;sudo /usr/local/my…...

聊城九洲建设有限公司网站/seo优化主要做什么

1、找寻支持QQ HTTP协议的服务器。大家也许会被一些假像所迷惑&#xff0c;也许会认为QQ的HTTP服务器是基于80口进行通信的&#xff08;如&#xff1a;218.17.209.23:80&#xff09;&#xff0c;其实不然&#xff0c;正真基于HTTP的服务器应该是&#xff1a;http://tqq.tencent…...

网站资料筹备/上海网站推广优化

你是否还在大量控制台窗口中监控容器&#xff0c;还是对使用终端命令充满热情&#xff1f;而使用Docker的图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;则可以更简单的对容器进行管理&#xff0c;并提高效率。而且它们都是免费的。PortainerPortainer是一款Web应用…...

徐州做网站费用/北京百度推广代理公司

2019独角兽企业重金招聘Python工程师标准>>> Jenkins是代码持续集成工具&#xff0c;Sonar则是一个代码质量管理平台。在编译代码时&#xff0c;可以使用SonarQube提供的sonar-maven-plugin插件执行执行sonar代码质量检查&#xff0c;将检查结果传给SonarQube服务器…...

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

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