机器人xacro设计+gazebo/rviz启动

news2024/11/19 5:46:30

机器人xacro设计+gazebo/rviz启动

  • 项目需求
  • 方案
    • 机器人的本体设计
      • 机器人本体集成car_gazebo.xacro
      • inertial惯性矩阵 head.xacro
      • 小车底盘base.xacro
      • 摄像头camera.xacro
      • 雷达laser.xacro
    • 机器joint关节控制器+传感器sensor设计
      • 机器人joint关节控制器move.xacro
      • 摄像头传感器camera_sensor.xacro
      • 雷达传感器laser_sensor.xacro
    • launch文件启动gazebo和rviz
      • car_gazebo.launch
      • car_rviz.launch

项目需求

创建一个机器人,包含本体、控制器、传感器。在gazebo物理引擎中加载真实世界模型,在rviz通过各种插件查看状态。

方案

首先,看一下整体的项目截图
在这里插入图片描述
urdf02_gazebo功能包下面有/config文件夹放置rviz的配置文件,/launch文件夹放置启动文件,/world文件夹放置gazebo的物理世界模型,/xacro文件夹放机器人模型文件,分别在/xacro当前目录下放机器人本体的xacro文件,以及在/xacro/gazebo文件夹下放控制和传感器文件,最终所有的xacro文件都集成进/xacro/car_gazebo.xacro中,即car_gazebo.xacro集成了机器人本体、控制器、传感器,值得注意的是,xacro集成了这么多个不同的 xacro文件,其本质上是将所有的xacro文件复制到一块的,所以不同的xacro文件可写同一个name,反正最终都会复制集成到同一个xacro文件下,car_gazebo.xacro如下所示。

机器人的本体设计

机器人本体集成car_gazebo.xacro

<robot name="car" xmlns:xacro="http://wiki.ros.org/xacro"> 
    <xacro:include filename="head.xacro" />
    <xacro:include filename="base.xacro" />
    <xacro:include filename="camera.xacro" />
    <xacro:include filename="laser.xacro" />
    
    <xacro:include filename="gazebo/move.xacro" />
    <xacro:include filename="gazebo/laser_sensor.xacro" />
    <xacro:include filename="gazebo/camera_sensor.xacro" />
</robot>

其中第一个head.xacro是计算inertial惯性矩阵的,因为gazebo是需要考虑真实物理引擎的,所以head.xacro里封装了宏(相当于函数,包含函数名和参数),每个宏函数都是标准的物体,如球,圆柱等,传参传入质量,长宽高半径等,宏函数就会自动计算惯性矩阵,宏函数在机器人本体设计直接调用即可。

inertial惯性矩阵 head.xacro

<robot name="base" xmlns:xacro="http://wiki.ros.org/xacro">
    <!-- Macro for inertia matrix
    head.xacro -->
    <xacro:macro name="sphere_inertial_matrix" params="m r">
        <inertial>
            <mass value="${m}" />
            <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
                iyy="${2*m*r*r/5}" iyz="0" 
                izz="${2*m*r*r/5}" />
        </inertial>
    </xacro:macro>

    <xacro:macro name="cylinder_inertial_matrix" params="m r h">
        <inertial>
            <mass value="${m}" />
            <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
                iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
                izz="${m*r*r/2}" /> 
        </inertial>
    </xacro:macro>

    <xacro:macro name="Box_inertial_matrix" params="m l w h">
       <inertial>
               <mass value="${m}" />
               <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
                   iyy="${m*(w*w + l*l)/12}" iyz= "0"
                   izz="${m*(w*w + h*h)/12}" />
       </inertial>
   </xacro:macro>
</robot>

以下是各个机器人本体连杆link的设计,包括小车底盘、摄像头、雷达,其中的inertial惯性矩阵用到了head.xacro的宏函数。

小车底盘base.xacro

<!--
    使用 xacro 优化 URDF 版的小车底盘实现:
    base.xacro
    实现思路:
    1.将一些常量、变量封装为 xacro:property
      比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 ....
    2.使用 宏 封装驱动轮以及支撑轮实现,调用相关宏生成驱动轮与支撑轮

-->
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 封装变量、常量 -->
    <!-- PI 值设置精度需要高一些,否则后续车轮翻转量计算时,可能会出现肉眼不能察觉的车轮倾斜,从而导致模型抖动 -->
    <xacro:property name="PI" value="3.1415926"/>
    <!-- 宏:黑色设置 -->
    <material name="black">
        <color rgba="0.0 0.0 0.0 1.0" />
    </material>
    <!-- 底盘属性 -->
    <xacro:property name="base_footprint_radius" value="0.001" /> <!-- base_footprint 半径  -->
    <xacro:property name="base_link_radius" value="0.1" /> <!-- base_link 半径 -->
    <xacro:property name="base_link_length" value="0.08" /> <!-- base_link 长 -->
    <xacro:property name="earth_space" value="0.015" /> <!-- 离地间距 -->
    <xacro:property name="base_link_m" value="0.5" /> <!-- 质量  -->

    <!-- 底盘 -->
    <link name="base_footprint">
      <visual>
        <geometry>
          <sphere radius="${base_footprint_radius}" />
        </geometry>
      </visual>
    </link>

    <link name="base_link">
      <visual>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <material name="yellow">
          <color rgba="0.5 0.3 0.0 0.5" />
        </material>
      </visual>
      <collision>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
      </collision>
      <xacro:cylinder_inertial_matrix m="${base_link_m}" r="${base_link_radius}" h="${base_link_length}" />

    </link>


    <joint name="base_link2base_footprint" type="fixed">
      <parent link="base_footprint" />
      <child link="base_link" />
      <origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
    </joint>
    <gazebo reference="base_link">
        <material>Gazebo/Yellow</material>
    </gazebo>

    <!-- 驱动轮 -->
    <!-- 驱动轮属性 -->
    <xacro:property name="wheel_radius" value="0.0325" /><!-- 半径 -->
    <xacro:property name="wheel_length" value="0.015" /><!-- 宽度 -->
    <xacro:property name="wheel_m" value="0.05" /> <!-- 质量  -->

    <!-- 驱动轮宏实现 -->
    <xacro:macro name="add_wheels" params="name flag">
      <link name="${name}_wheel">
        <visual>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
          <material name="black" />
        </visual>
        <collision>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
        </collision>
        <xacro:cylinder_inertial_matrix m="${wheel_m}" r="${wheel_radius}" h="${wheel_length}" />

      </link>

      <joint name="${name}_wheel2base_link" type="continuous">
        <parent link="base_link" />
        <child link="${name}_wheel" />
        <origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
        <axis xyz="0 1 0" />
      </joint>

      <gazebo reference="${name}_wheel">
        <material>Gazebo/Red</material>
      </gazebo>

    </xacro:macro>
    <xacro:add_wheels name="left" flag="1" />
    <xacro:add_wheels name="right" flag="-1" />
    <!-- 支撑轮 -->
    <!-- 支撑轮属性 -->
    <xacro:property name="support_wheel_radius" value="0.0075" /> <!-- 支撑轮半径 -->
    <xacro:property name="support_wheel_m" value="0.03" /> <!-- 质量  -->

    <!-- 支撑轮宏 -->
    <xacro:macro name="add_support_wheel" params="name flag" >
      <link name="${name}_wheel">
        <visual>
            <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <material name="black" />
        </visual>
        <collision>
            <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
        </collision>
        <xacro:sphere_inertial_matrix m="${support_wheel_m}" r="${support_wheel_radius}" />
      </link>

      <joint name="${name}_wheel2base_link" type="continuous">
          <parent link="base_link" />
          <child link="${name}_wheel" />
          <origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
          <axis xyz="1 1 1" />
      </joint>
      <gazebo reference="${name}_wheel">
        <material>Gazebo/Red</material>
      </gazebo>
    </xacro:macro>

    <xacro:add_support_wheel name="front" flag="1" />
    <xacro:add_support_wheel name="back" flag="-1" />
</robot>

摄像头camera.xacro

<!-- 摄像头相关的 xacro 文件  camera.xacro -->
<robot name="my_camera" xmlns:xacro="http://wiki.ros.org/xacro">
    <!-- 摄像头属性 -->
    <xacro:property name="camera_length" value="0.01" /> <!-- 摄像头长度(x) -->
    <xacro:property name="camera_width" value="0.025" /> <!-- 摄像头宽度(y) -->
    <xacro:property name="camera_height" value="0.025" /> <!-- 摄像头高度(z) -->
    <xacro:property name="camera_x" value="0.08" /> <!-- 摄像头安装的x坐标 -->
    <xacro:property name="camera_y" value="0.0" /> <!-- 摄像头安装的y坐标 -->
    <xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" /> <!-- 摄像头安装的z坐标:底盘高度 / 2 + 摄像头高度 / 2  -->

    <xacro:property name="camera_m" value="0.01" /> <!-- 摄像头质量 -->

    <!-- 摄像头关节以及link -->
    <link name="camera">
        <visual>
            <geometry>
                <box size="${camera_length} ${camera_width} ${camera_height}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
        <collision>
            <geometry>
                <box size="${camera_length} ${camera_width} ${camera_height}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>
        <xacro:Box_inertial_matrix m="${camera_m}" l="${camera_length}" w="${camera_width}" h="${camera_height}" />
    </link>

    <joint name="camera2base_link" type="fixed">
        <parent link="base_link" />
        <child link="camera" />
        <origin xyz="${camera_x} ${camera_y} ${camera_z}" />
    </joint>
    <gazebo reference="camera">
        <material>Gazebo/Blue</material>
    </gazebo>
</robot>

雷达laser.xacro

<!--
    小车底盘添加雷达
    laser.xacro
-->
<robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro">

    <!-- 雷达支架 -->
    <xacro:property name="support_length" value="0.15" /> <!-- 支架长度 -->
    <xacro:property name="support_radius" value="0.01" /> <!-- 支架半径 -->
    <xacro:property name="support_x" value="0.0" /> <!-- 支架安装的x坐标 -->
    <xacro:property name="support_y" value="0.0" /> <!-- 支架安装的y坐标 -->
    <xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2  -->

    <xacro:property name="support_m" value="0.02" /> <!-- 支架质量 -->

    <link name="support">
        <visual>
            <geometry>
                <cylinder radius="${support_radius}" length="${support_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="red">
                <color rgba="0.8 0.2 0.0 0.8" />
            </material>
        </visual>

        <collision>
            <geometry>
                <cylinder radius="${support_radius}" length="${support_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>

        <xacro:cylinder_inertial_matrix m="${support_m}" r="${support_radius}" h="${support_length}" />

    </link>

    <joint name="support2base_link" type="fixed">
        <parent link="base_link" />
        <child link="support" />
        <origin xyz="${support_x} ${support_y} ${support_z}" />
    </joint>

    <gazebo reference="support">
        <material>Gazebo/White</material>
    </gazebo>

    <!-- 雷达属性 -->
    <xacro:property name="laser_length" value="0.05" /> <!-- 雷达长度 -->
    <xacro:property name="laser_radius" value="0.03" /> <!-- 雷达半径 -->
    <xacro:property name="laser_x" value="0.0" /> <!-- 雷达安装的x坐标 -->
    <xacro:property name="laser_y" value="0.0" /> <!-- 雷达安装的y坐标 -->
    <xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2  -->

    <xacro:property name="laser_m" value="0.1" /> <!-- 雷达质量 -->

    <!-- 雷达关节以及link -->
    <link name="laser">
        <visual>
            <geometry>
                <cylinder radius="${laser_radius}" length="${laser_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
        <collision>
            <geometry>
                <cylinder radius="${laser_radius}" length="${laser_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>
        <xacro:cylinder_inertial_matrix m="${laser_m}" r="${laser_radius}" h="${laser_length}" />
    </link>

    <joint name="laser2support" type="fixed">
        <parent link="support" />
        <child link="laser" />
        <origin xyz="${laser_x} ${laser_y} ${laser_z}" />
    </joint>
    <gazebo reference="laser">
        <material>Gazebo/Black</material>
    </gazebo>
</robot>

以上是机器人本体的连杆link部件设计,那么小车还需要控制器还有上面的传感器真实引用,关于这部分内容我放在了/gazebo文件下。

机器joint关节控制器+传感器sensor设计

控制器也是通过xacro文件实现,小车动起来主要是通过joint关节传动,比如小车左轮与地盘连接的joint关节,控制关节转动即可,由于小车有两个驱动轮,所以joint驱动也封装成宏函数来实现。

机器人joint关节控制器move.xacro

<robot name="my_car_move" xmlns:xacro="http://wiki.ros.org/xacro">

    <!-- 传动实现:用于连接控制器与关节 /gazebo/move.xacro -->
    <xacro:macro name="joint_trans" params="joint_name">
        <!-- Transmission is important to link the joints and the controller -->
        <transmission name="${joint_name}_trans">
            <type>transmission_interface/SimpleTransmission</type>
            <joint name="${joint_name}">
                <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
            </joint>
            <actuator name="${joint_name}_motor">
                <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
                <mechanicalReduction>1</mechanicalReduction>
            </actuator>
        </transmission>
    </xacro:macro>

    <!-- 每一个驱动轮都需要配置传动装置 -->
    <xacro:joint_trans joint_name="left_wheel2base_link" />
    <xacro:joint_trans joint_name="right_wheel2base_link" />

    <!-- 控制器 -->
    <gazebo>
        <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
            <rosDebugLevel>Debug</rosDebugLevel>
            <publishWheelTF>true</publishWheelTF>
            <robotNamespace>/</robotNamespace>
            <publishTf>1</publishTf>
            <publishWheelJointState>true</publishWheelJointState>
            <alwaysOn>true</alwaysOn>
            <updateRate>100.0</updateRate>
            <legacyMode>true</legacyMode>
            <leftJoint>left_wheel2base_link</leftJoint> <!-- 左轮 -->
            <rightJoint>right_wheel2base_link</rightJoint> <!-- 右轮 -->
            <wheelSeparation>${base_link_radius * 2}</wheelSeparation> <!-- 车轮间距 -->
            <wheelDiameter>${wheel_radius * 2}</wheelDiameter> <!-- 车轮直径 -->
            <broadcastTF>1</broadcastTF>
            <wheelTorque>30</wheelTorque>
            <wheelAcceleration>1.8</wheelAcceleration>
            <commandTopic>cmd_vel</commandTopic> <!-- 运动控制话题 -->
            <odometryFrame>odom</odometryFrame> 
            <odometryTopic>odom</odometryTopic> <!-- 里程计话题 -->
            <robotBaseFrame>base_footprint</robotBaseFrame> <!-- 根坐标系 -->
        </plugin>
    </gazebo>

</robot>

接下来是传感器的配置,因为机器人本体已经有了camera连杆和laser连杆,所以现在需要给这两个存在的连杆配上传感器,也就是将传感器映射到连杆中。引用方式是gazebo reference=“连杆名”,连杆名在机器人本体连杆文件中,保持一致。

摄像头传感器camera_sensor.xacro

<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro">
  <!-- 被引用的link
  /gazebo/camera_sensor.xacro -->
  <gazebo reference="camera">
    <!-- 类型设置为 camara -->
    <sensor type="camera" name="camera_node">
      <update_rate>30.0</update_rate> <!-- 更新频率 -->
      <!-- 摄像头基本信息设置 -->
      <camera name="head">
        <horizontal_fov>1.3962634</horizontal_fov>
        <image>
          <width>1280</width>
          <height>720</height>
          <format>R8G8B8</format>
        </image>
        <clip>
          <near>0.02</near>
          <far>300</far>
        </clip>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.007</stddev>
        </noise>
      </camera>
      <!-- 核心插件 -->
      <plugin name="gazebo_camera" filename="libgazebo_ros_camera.so">
        <alwaysOn>true</alwaysOn>
        <updateRate>0.0</updateRate>
        <cameraName>/camera</cameraName>
        <imageTopicName>image_raw</imageTopicName>
        <cameraInfoTopicName>camera_info</cameraInfoTopicName>
        <frameName>camera</frameName>
        <hackBaseline>0.07</hackBaseline>
        <distortionK1>0.0</distortionK1>
        <distortionK2>0.0</distortionK2>
        <distortionK3>0.0</distortionK3>
        <distortionT1>0.0</distortionT1>
        <distortionT2>0.0</distortionT2>
      </plugin>
    </sensor>
  </gazebo>
</robot>

雷达传感器laser_sensor.xacro

<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro">

  <!-- 雷达 /gazebo/laser_sensor.xacro-->
  <gazebo reference="laser">
    <sensor type="ray" name="rplidar">
      <pose>0 0 0 0 0 0</pose>
      <visualize>true</visualize>
      <update_rate>5.5</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>360</samples>
            <resolution>1</resolution>
            <min_angle>-3</min_angle>
            <max_angle>3</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.10</min>
          <max>30.0</max>
          <resolution>0.01</resolution>
        </range>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.01</stddev>
        </noise>
      </ray>
      <plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
        <topicName>/scan</topicName>
        <frameName>laser</frameName>
      </plugin>
    </sensor>
  </gazebo>

</robot>

好了,终于完成了机器人的整体设计了,现在机器人有了本体,还有了两轮差速控制器,还有了传感器。

接下来就让机器人通过launch文件启动gazebo和rviz中吧。

launch文件启动gazebo和rviz

分别通过launch来启动gazebo和rviz,有启动先后顺序的,因为car_gazebo.xacro先在car_gazebo.launch中加载到参数服务器中,所以要先启动car_gazebo.launch,并且在car_rviz.launch不需要加载car_gazebo.xacro文件,因为car_gazebo.launch已经将其加载参数服务器了。

car_gazebo.launch

<launch>
    <!-- car_gazebo.launch
    将 xacro 文件的内容加载到参数服务器 -->
    <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/xacro/car_gazebo.xacro" />

    <!-- 启动 gazebo -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(find urdf02_gazebo)/world/box_house.world" />
    </include>

    <!-- 在 gazebo 中显示机器人模型 -->
    <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
</launch>

car_rviz.launch

<launch>
    <!-- car_rviz.launch
    启动 rviz,加载rviz配置 -->
    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf02_gazebo)/config/show.rviz"/>

    <!-- 关节以及机器人状态发布节点 -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

</launch>

参考来源
【Autolabor初级教程】ROS机器人入门
URDF集成Gazebo

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

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

相关文章

Metabase学习教程:系统管理-7

使用MetabaseAPI MetabaseAPI简介。 本文介绍如何使用Metabase的API。我们自己使用该API连接前端和后端&#xff0c;因此您可以编写Metabase几乎可以执行的所有操作。 警告&#xff1a;MetabaseAPI可能会更改 开始之前有两个注意事项&#xff1a; API可能会更改。API与前端…

软件测试要学会哪些东西才能拿2w+的工资?

软件开发人员的月薪达到2万还是比较轻松的&#xff0c;但是软件测试人员想要月薪过万的话&#xff0c;我认为可以从两个方面去考虑&#xff1a; 1. 一种就是项目的测试负责人&#xff1a;测试人员需要对软件的整体性能改进提出建设性方案&#xff0c;所以很多软件测试人员最终…

数据结构和算法之《栈》详解

标题&#xff1a;栈的思路及代码实现 作者&#xff1a;Ggggggtm 寄语&#xff1a;与其忙着诉苦&#xff0c;不如低头赶路&#xff0c;奋路前行&#xff0c;终将遇到一番好风景 文章目录&#xff1a; 一、栈的概念及结构 1、1 栈的概念 1、2 栈的结构 二、栈的思路及代码实现详解…

电脑技巧:推荐5个非常实用的软件

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

uniapp 之使用 u-upload 组件来实现图片上传

uniapp 之使用 u-upload 组件来实现图片上传前言一、官方示例用法分析二、关闭自动上传,使用手动上传的方式,代码html 代码js 代码css 代码总结分析前言 在使用 uniapp 开发的微信小程序中使用了图片上传功能,使用了 uniapp 的图片上传组件 注意&#xff1a;我这里后端接口接收…

小程序开发平台

小程序开发平台顾名思义就是一个可以开发小程序的地方。 小程序开发平台&#xff1a;【电脑浏览器输入3M.FKW.COM了解详情】 适合群体&#xff1a;企业、机构、个体户 小程序开发方式&#xff1a; 自建——可以通过套用小程序模板&#xff0c;利用拖拽式小程序开发工具&…

某组态软件工程文件加密机制探究

某组态软件工程文件加密机制探究 前言 在工业自动化控制领域&#xff0c;组态软件是数据采集与过程控制的专用软件&#xff0c;是实现人机交互必不可少的工具。工程设计人员使用组态软件在PC机上进行工程画面组态的编辑&#xff0c;然后把编译后的组态逻辑通过以太网或串口下载…

HSRP协议(思科私有)/VRRP协议(公有)

数据来源 1、HSRP热备份路由协议&#xff08;备份网关&#xff09; 出现背景&#xff1a; 如下图一个公司拉两条网线一条用来备份网关是192.168.0.253&#xff0c;平时用的网关是254&#xff0c;如果网关是254的这条网线出问题了就可以使用备份不影响公司让人员上网&#xff…

2022最新版 Java 学习线路图

第 1 阶段 - 企业级开发 - java 基础 学习掌握本阶段的内容&#xff0c;可以实现诸如迅雷下载软件、QQ 聊天客户端、中小网站&#xff0c;例如&#xff1a;小型旅游网站、小型电商网站的开发 第 2 阶段 - 企业及开发 - 基础框架 学习掌握本阶段内容&#xff0c;可以快速、规范的…

CRC校验——以SHT4xA温湿度传感器为例

CRC校验——以SHT4xA温湿度传感器为例一、简介二、计算方法&#xff08;一&#xff09;步骤&#xff08;二&#xff09;参考代码&#xff08;C语言&#xff09;&#xff08;三&#xff09;检验&#xff1a;CRC(0xBEEF) 0x92三、参考一、简介 循环冗余校验码&#xff08;CRC&am…

[附源码]计算机毕业设计JAVA疫情防控下高校教职工健康信息管理系统

[附源码]计算机毕业设计JAVA疫情防控下高校教职工健康信息管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

试剂盒和示踪剂—艾美捷FLIVO探针活体凋亡检测分析

针对FLIVO(FLuorescence in vIVO)探针的研究&#xff0c;本篇文章推荐艾美捷ImmunoChemistry&#xff08;ICT&#xff09;FLIVO探针系列的&#xff1a;天冬氨酸蛋白酶(Caspases)活性检测试剂盒&#xff0c;及 FLIVO示踪剂&#xff0c;主要用于细胞凋亡活体检测&#xff0c;助力…

大型分布式系统下缓存应该怎么玩,才能用得高效

大家好&#xff0c;今天我们来聊一聊在大型分布式系统中&#xff0c;缓存应该怎么玩&#xff0c;从毕业到现在也有三年多了&#xff0c;大大小小的系统也经历了几十个&#xff0c;今天就从各个角度来讨论一下&#xff0c;我们的不同的缓存应该怎么玩&#xff0c;才能用的高效。…

N皇后问题(分支限界法)

问题描述&#xff1a; 在 n * n 格的棋盘上放置彼此不受攻击的 n 个皇后。按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题等价于在 n * n 的棋盘上放置 n 个皇后&#xff0c;任何 2个皇后不放在同一行或同一列或同一斜线上…

Ansys Speos | 新型计算方法:使用 GPU 提升计算速率

前言 Speos 在2022R2版本中正式推出 GPU 计算功能&#xff0c;相比于 CPU 计算&#xff0c;相同HPC32配置&#xff0c;高性能显卡在仿真计算中将会更显计算优势&#xff0c;在仿真数据量大、材料属性复杂、光源种类多的条件下&#xff0c;Speos 视觉模拟会消耗更多仿真计算时间…

ARM异常处理(1):异常类型、优先级分组和异常向量表

本系列文章将以Cortex-M3内核为例&#xff0c;对ARM的异常(exception)进行分析。 文章目录1 异常类型2 优先级3 向量表1 异常类型 Cortex-M3提供了一个功能丰富的异常体系结构&#xff0c;它支持很多系统异常和外部中断。异常编号1-15表示系统异常&#xff0c;16及以上表示外部…

0116 查找算法 Day5

剑指 Offer 04. 二维数组中的查找 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该…

2022快手电商短视频运营白皮书:Q2对比Q1GMV总值增长率达12%

1、2022快手电商短视频运营白皮书&#xff1a;Q2对比Q1GMV总值增长率达12%新榜讯 12月2日&#xff0c;快手电商发布《2022快手电商短视频运营白皮书》。白皮书数据显示&#xff0c;2022年4-6月&#xff0c;随着平台商家对短视频渠道的认知提升&#xff0c;挂车短视频生产量不断…

【人脸识别】MVFace:一个优于CosFace和ArcFace的人脸识别损失

论文题目&#xff1a;《Mis-classifified Vector Guided Softmax Loss for Face Recognition》 论文地址&#xff1a;https://arxiv.org/pdf/1912.00833v1.pdf 代码地址&#xff1a;http://www.cbsr.ia.ac.cn/users/xiaobowang/ 1.背景 迄今为止&#xff0c;提出了几种基于mar…

Hashing to elliptic curve算法改进

1. 引言 前序博客有&#xff1a; ECDSA VS Schnorr signature VS BLS signature 第3节“BLS签名” 私钥pkpkpk&#xff0c;对应的公钥为PpkGPpk\times GPpkG。待签名消息mmm。 BLS signature的签名流程为&#xff1a; 1&#xff09;通过H(m)H(m)H(m)将消息mmm映射为point o…