ros1仿真导航机器人 基础传感器数据读取

仅为学习记录和一些自己的思考,不具有参考意义。

1 仿真环境

gazebo、rviz、ros1

2 机器人模型

<?xml version="1.0"?>
<robot name="wpb_home_gazebo">

<link name="base_footprint">
  <visual>
    <origin xyz="0 0 0" rpy="0 0 0" />
    <geometry>
      <box size="0.05 0.05 0.001" />
    </geometry>
  </visual>
</link>

<joint name="base_joint" type="fixed">
  <origin xyz="0 0 0" rpy="0 0 0" />
  <parent link="base_footprint"/>
  <child link="base_link" />
</joint>

<!-- base -->
<link name="base_link">
  <visual>
   <geometry>
    <box size="0.01 0.01 0.001" />
   </geometry>
   <origin rpy = "0 0 0" xyz = "0 0 0"/>
  </visual>
</link>

<!-- body -->
<link name = "body_link">
  <visual>
    <geometry>
      <mesh filename="package://why_simulation/meshes/wpb_home/wpb_home_std.dae" scale="1 1 1"/>
    </geometry>
    <origin rpy = "1.57 0 1.57" xyz = "-.225 -0.225 0"/>
  </visual>
  <collision>
    <origin xyz="0.001 0 .065" rpy="0 0 0" />
    <geometry>
      <cylinder length="0.13" radius="0.226"/>
    </geometry>
  </collision>
  <inertial>
    <mass value="20"/>
    <inertia ixx="4.00538" ixy="0.0" ixz="0.0" iyy="4.00538" iyz="0.0" izz="0.51076"/>
  </inertial>
</link>
<joint name = "base_to_body" type = "fixed">
  <parent link = "base_link"/>
  <child link = "body_link"/>
  <origin rpy="0 0 0" xyz="0 0 0"/> <!--pos-->
</joint>
<!-- top of base -->
<link name = "base_top_link">
  <collision>
    <origin xyz="0 0 0" rpy="0 0 0" />
    <geometry>
      <box size="0.33 0.31 0.01"/>
    </geometry>
  </collision>
  <inertial>
    <mass value="0.01"/>
    <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
  </inertial>
</link>
<joint name = "body_to_top" type = "fixed">
  <parent link = "body_link"/>
  <child link = "base_top_link"/>
  <origin rpy="0 0 0" xyz="0.01 0 0.2"/> <!--pos-->
</joint>
<!-- back -->
<link name = "body_back_link">
  <collision>
    <origin xyz="0 0 0" rpy="0 0 0" />
    <geometry>
      <box size="0.03 0.23 1.05"/>
    </geometry>
  </collision>
  <inertial>
    <mass value="0.01"/>
    <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
  </inertial>
</link>
<joint name = "body_to_back" type = "fixed">
  <parent link = "base_top_link"/>
  <child link = "body_back_link"/>
  <origin rpy="0 0.31 0" xyz="-0.038 0 0.5"/> <!--pos-->
</joint>
<!-- head -->
<link name = "head_link">
  <collision>
    <origin xyz="0 0 0" rpy="0 0 0" />
    <geometry>
      <box size="0.07 0.28  0.06"/>
    </geometry>
  </collision>
  <inertial>
    <mass value="0.01"/>
    <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
  </inertial>
</link>
<joint name = "body_to_head" type = "fixed">
  <parent link = "base_top_link"/>
  <child link = "head_link"/>
  <origin rpy="0 0.27 0" xyz="0.155 0 1.17"/> <!--pos-->
</joint>
<!-- front -->
<link name = "front_link">
  <collision>
    <origin xyz="0 0 0" rpy="0 0 0" />
    <geometry>
     <cylinder length="1.1" radius="0.01"/>
    </geometry>
  </collision>
  <inertial>
    <mass value="0.01"/>
    <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
  </inertial>
</link>
<joint name = "body_to_front" type = "fixed">
  <parent link = "base_top_link"/>
  <child link = "front_link"/>
  <origin rpy="0 0 0" xyz="0.15 0 0.55"/> <!--pos-->
</joint>

<!-- Lidar -->
<link name = "laser">
  <visual>
   <geometry>
      <cylinder length="0.001" radius="0.001"/>
   </geometry>
   <origin rpy = "0 0 0" xyz = "0 0 0"/>
  </visual>
</link>
<joint name="laser_joint" type="fixed">
    <origin rpy="0 0 0" xyz="0 0 0.15"  /> <!--pos-->
    <parent link="base_link" />
    <child link="laser" />
</joint>

<!-- Kinect -->
<link name = "kinect2_dock">
  <visual>
   <geometry>
    <!-- <box size=".01 .25 .07"/>-->
    <box size="0.001 0.001 0.001"/>
   </geometry>
   <origin rpy = "0 0 0" xyz = "0 0 0"/>
  </visual>
</link>
<joint name="kinect_height" type="fixed">
  <parent link="base_link"/>
  <child link="kinect2_dock"/>
  <origin xyz="0.145 -0.013 1.37" rpy="0 0 0"/> 
</joint>

<link name = "kinect2_head_frame">
  <visual>
   <geometry>
    <box size="0.001 0.001 0.001"/>
   </geometry>
   <origin xyz = "0 0 0" rpy = "0 0 0"/>
  </visual>
</link>
<!--kinect_pitch -->
<joint name="kinect_pitch" type="fixed">
  <origin xyz="0 0 0" rpy="0 0.5 0" /> 
  <parent link="kinect2_dock" />
  <child link="kinect2_head_frame" />
</joint>

<link name = "kinect2_front_frame">
  <visual>
   <geometry>
    <box size="0.001 0.001 0.001"/>
   </geometry>
   <origin xyz = "0 0 0" rpy = "0 0 0"/>
  </visual>
</link>
<joint name="kinect_head" type="fixed">
  <origin xyz="0 0 0" rpy=" 0 1.57 0" /> 
  <parent link="kinect2_head_frame" />
  <child link="kinect2_front_frame" />
</joint>
<link name = "kinect2_ir_optical_frame">
  <visual>
   <geometry>
    <!-- <box size=".25 .04 .07"/>-->
    <box size="0.001 0.001 0.001"/>
   </geometry>
   <origin xyz = "0 0 0" rpy = "0 0 0"/>
  </visual>
</link>
<joint name="kinect_ir_trans" type="fixed">
  <origin xyz="0 0 0" rpy="0 0 -1.57" /> 
  <parent link="kinect2_front_frame" />
  <child link="kinect2_ir_optical_frame" />
</joint>

<link name = "kinect2_camera_frame">
  <visual>
   <geometry>
    <box size="0.001 0.001 0.001"/>
   </geometry>
   <origin rpy = "0 0 0" xyz = "0 0 0" />
  </visual>
</link>
<joint name="kinect_camra_joint" type="fixed">
    <origin xyz="0 0 0" rpy="3.1415926 0 -1.5707963" />
    <parent link="kinect2_ir_optical_frame" />
    <child link="kinect2_camera_frame" />
</joint>

<link name = "kinect2_rgb_optical_frame">
  <visual>
   <geometry>
    <box size="0.001 0.001 0.001"/>
   </geometry>
   <origin rpy = "0 0 0" xyz = "0 0 0" />
  </visual>
</link>
<joint name="kinect_hd_joint" type="fixed">
    <origin xyz="0 0 0" rpy="0 1.5707963 0" />
    <parent link="kinect2_camera_frame" />
    <child link="kinect2_rgb_optical_frame" />
</joint>

<!-- Gazebo plugin for WPR -->
<gazebo>
  <plugin name="base_controller" filename="libwpr_plugin.so">
    <publishOdometryTf>true</publishOdometryTf>
    <commandTopic>cmd_vel</commandTopic>
    <odometryTopic>odom</odometryTopic>
    <odometryFrame>odom</odometryFrame>
    <odometryRate>20.0</odometryRate>
    <robotBaseFrame>base_footprint</robotBaseFrame>
  </plugin>
</gazebo>

<!-- Gazebo plugin for RpLidar A2 -->
<gazebo reference="laser">
  <sensor type="ray" name="rplidar_sensor">
    <pose>0 0 0.06 0 0 0</pose>
    <visualize>true</visualize>
    <update_rate>10</update_rate>
    <ray>
      <scan>
        <horizontal>
          <samples>360</samples>
          <resolution>1</resolution>
          <min_angle>-3.14159265</min_angle>
          <max_angle>3.14159265</max_angle>
        </horizontal>
      </scan>
      <range>
        <min>0.24</min>
        <max>6.0</max>
        <resolution>0.01</resolution>
      </range>
      <noise>
        <type>gaussian</type>
        <mean>0.0</mean>
        <stddev>0.01</stddev>
      </noise>
    </ray>
    <plugin name="rplidar_ros_controller" filename="libgazebo_ros_laser.so">
      <topicName>scan</topicName>
      <frameName>laser</frameName>
    </plugin>
  </sensor>
</gazebo>

<!-- Gazebo plugin for Kinect v2 -->
<gazebo reference="kinect2_head_frame">
  <sensor type="depth" name="kinect2_depth_sensor" >
    <always_on>true</always_on>
    <update_rate>10.0</update_rate>
    <camera name="kinect2_depth_sensor">
      <horizontal_fov>1.221730456</horizontal_fov>
      <image>
          <width>512</width>
          <height>424</height>
          <format>B8G8R8</format>
      </image>
      <clip>
          <near>0.5</near>
          <far>6.0</far>
      </clip>
      <noise>
          <type>gaussian</type>
          <mean>0.1</mean>
          <stddev>0.07</stddev>
      </noise>
    </camera>
    <plugin name="kinect2_depth_control" filename="libgazebo_ros_openni_kinect.so">
        <cameraName>kinect2/sd</cameraName>
        <alwaysOn>true</alwaysOn>
        <updateRate>20.0</updateRate>
        <imageTopicName>image_ir_rect</imageTopicName>
        <depthImageTopicName>image_depth_rect</depthImageTopicName>
        <pointCloudTopicName>points</pointCloudTopicName>
        <cameraInfoTopicName>depth_camera_info</cameraInfoTopicName>
        <frameName>kinect2_ir_optical_frame</frameName>
        <pointCloudCutoff>0.5</pointCloudCutoff>
        <pointCloudCutoffMax>6.0</pointCloudCutoffMax>
        <baseline>0.1</baseline>
        <distortionK1>0.0</distortionK1>
        <distortionK2>0.0</distortionK2>
        <distortionK3>0.0</distortionK3>
        <distortionT1>0.0</distortionT1>
        <distortionT2>0.0</distortionT2>
    </plugin>
  </sensor>
</gazebo>
<gazebo reference="kinect2_rgb_optical_frame">
    <sensor type="camera" name="kinect2_rgb_sensor">
        <always_on>true</always_on>
        <update_rate>20.0</update_rate>
        <camera name="kinect2_rgb_sensor">
          <horizontal_fov>1.221730456</horizontal_fov>
          <image>
              <width>1920</width>
              <height>1080</height>
              <format>B8G8R8</format>
          </image>
          <clip>
              <near>0.2</near>
              <far>10.0</far>
          </clip>
          <noise>
              <type>gaussian</type>
              <mean>0.0</mean>
              <stddev>0.007</stddev>
          </noise>
        </camera>
        <plugin name="kinect2_rgb_controller" filename="libgazebo_ros_camera.so">
          <alwaysOn>true</alwaysOn>
          <update_rate>20.0</update_rate>
          <cameraName>kinect2/hd</cameraName>
          <imageTopicName>image_color_rect</imageTopicName>
          <cameraInfoTopicName>camera_info</cameraInfoTopicName>
          <frameName>kinect2_rgb_optical_frame</frameName>
        </plugin>
    </sensor>
</gazebo>

<gazebo reference="kinect2_head_frame">
    <sensor type="camera" name="kinect2_qhd_rgb_sensor">
        <always_on>true</always_on>
        <update_rate>20.0</update_rate>
        <camera name="kinect2_qhd_rgb_sensor">
          <horizontal_fov>1.221730456</horizontal_fov>
          <image>
              <width>960</width>
              <height>540</height>
              <format>R8G8B8</format>
          </image>
          <clip>
              <near>0.2</near>
              <far>10.0</far>
          </clip>
        </camera>
        <plugin name="kinect2_qhd_rgb_controller" filename="libgazebo_ros_camera.so">
          <alwaysOn>true</alwaysOn>
          <update_rate>20.0</update_rate>
          <cameraName>kinect2/qhd</cameraName>
          <imageTopicName>image_color_rect</imageTopicName>
          <cameraInfoTopicName>camera_info</cameraInfoTopicName>
          <frameName>kinect2_head_frame</frameName>
        </plugin>
    </sensor>
</gazebo>

<!-- IMU plugin for 'body_link' -->
<gazebo reference="body_link">
  <gravity>true</gravity>
  <sensor name="imu_sensor" type="imu">
    <always_on>true</always_on>
    <update_rate>100</update_rate>
    <visualize>true</visualize>
    <topic>__default_topic__</topic>
    <plugin filename="libgazebo_ros_imu_sensor.so" name="imu_plugin">
      <topicName>imu/data</topicName>
      <bodyName>body_link</bodyName>
      <updateRateHZ>100.0</updateRateHZ>
      <gaussianNoise>0.0</gaussianNoise>
      <xyzOffset>0 0 0</xyzOffset>
      <rpyOffset>0 0 0</rpyOffset>
      <frameName>imu_link</frameName>
    </plugin>
    <pose>0 0 0 0 0 0</pose>
  </sensor>
</gazebo>

</robot>

3启动launch文件

roslaunch why_simulation why_simple.launch

<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find why_simulation)/worlds/why_simple.world"/>
    <arg name="paused" value="false"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
    <arg name="recording" value="false"/>
    <arg name="debug" value="false"/>
  </include>

  <!-- Spawn the objects into Gazebo -->
  <node name="bookshelft" pkg="gazebo_ros" type="spawn_model" args="-file $(find why_simulation)/models/bookshelft.model -x 3.0 -y 0.2 -z 0 -Y 3.14159 -urdf -model bookshelft" />
  <node name="bottle" pkg="gazebo_ros" type="spawn_model" args="-file $(find why_simulation)/models/bottles/red_bottle.model -x 2.8 -y 0 -z 0.6 -Y 0 -urdf -model red_bottle" />

  <!-- Spawn a robot into Gazebo -->
  <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file $(find why_simulation)/models/wpb_home.model -urdf -model wpb_home" />

  <!-- Robot Description -->
  <arg name="model" default="$(find why_simulation)/models/wpb_home.model"/>
  <param name="robot_description" command="$(find xacro)/xacro $(arg model)" />
  <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>

rviz

4Topic话题查看

rostopic list

/clock
/cmd_vel
/gazebo/link_states
/gazebo/model_states
/gazebo/parameter_descriptions
/gazebo/parameter_updates
/gazebo/set_link_state
/gazebo/set_model_state
/imu/data
/joint_states
/kinect2/hd/camera_info
/kinect2/hd/image_color_rect
/kinect2/hd/image_color_rect/compressed
/kinect2/hd/image_color_rect/compressed/parameter_descriptions
/kinect2/hd/image_color_rect/compressed/parameter_updates
/kinect2/hd/image_color_rect/compressedDepth
/kinect2/hd/image_color_rect/compressedDepth/parameter_descriptions
/kinect2/hd/image_color_rect/compressedDepth/parameter_updates
/kinect2/hd/image_color_rect/theora
/kinect2/hd/image_color_rect/theora/parameter_descriptions
/kinect2/hd/image_color_rect/theora/parameter_updates
/kinect2/hd/parameter_descriptions
/kinect2/hd/parameter_updates
/kinect2/qhd/camera_info
/kinect2/qhd/image_color_rect
/kinect2/qhd/image_color_rect/compressed
/kinect2/qhd/image_color_rect/compressed/parameter_descriptions
/kinect2/qhd/image_color_rect/compressed/parameter_updates
/kinect2/qhd/image_color_rect/compressedDepth
/kinect2/qhd/image_color_rect/compressedDepth/parameter_descriptions
/kinect2/qhd/image_color_rect/compressedDepth/parameter_updates
/kinect2/qhd/image_color_rect/theora
/kinect2/qhd/image_color_rect/theora/parameter_descriptions
/kinect2/qhd/image_color_rect/theora/parameter_updates
/kinect2/qhd/parameter_descriptions
/kinect2/qhd/parameter_updates
/kinect2/sd/depth/camera_info
/kinect2/sd/depth_camera_info
/kinect2/sd/image_depth_rect
/kinect2/sd/image_ir_rect
/kinect2/sd/image_ir_rect/compressed
/kinect2/sd/image_ir_rect/compressed/parameter_descriptions
/kinect2/sd/image_ir_rect/compressed/parameter_updates
/kinect2/sd/image_ir_rect/compressedDepth
/kinect2/sd/image_ir_rect/compressedDepth/parameter_descriptions
/kinect2/sd/image_ir_rect/compressedDepth/parameter_updates
/kinect2/sd/image_ir_rect/theora
/kinect2/sd/image_ir_rect/theora/parameter_descriptions
/kinect2/sd/image_ir_rect/theora/parameter_updates
/kinect2/sd/parameter_descriptions
/kinect2/sd/parameter_updates
/kinect2/sd/points
/odom
/rosout
/rosout_agg
/scan
/tf
/tf_static

5运动控制与传感器数据读取

运动控制

rosrun why_test test_vel

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

int main(int argc, char  *argv[])
{
    ros::init(argc,argv,"test_vel");

    ros::NodeHandle nh;
    ros::Publisher pub_=nh.advertise<geometry_msgs::Twist>("/cmd_vel",10);

    ros::Rate rate(10);
    while (ros::ok())
    {
        auto twist=geometry_msgs::Twist();
        twist.linear.x=0.2;
        twist.angular.z=0.2;
        pub_.publish(twist);
        rate.sleep();
    }
    
    return 0;
}

激光雷达数据读取

rosrun why_test test_lidar

#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>


void LidarCallback(const sensor_msgs::LaserScan msg)
{
    float dMidDist=msg.ranges[180];
    std::cout<<"distance="<<dMidDist<<std::endl;
}



int main(int argc, char *argv[])
{
    ros::init(argc,argv,"test_lidar");

    ros::NodeHandle nh;
    ros::Subscriber sub_=nh.subscribe("/scan",10,&LidarCallback);

    ros::spin();

    return 0;
}

IMU数据读取

rosrun why_test test_imu

#include "ros/ros.h"
#include "sensor_msgs/Imu.h"
#include "tf/tf.h"


void IMUCallback(const 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("roll= %.0f pitch= %.0f yaw= %.0f", roll, pitch, yaw);
}

int main(int argc, char **argv)
{
    ros::init(argc,argv, "test_imu"); 

    ros::NodeHandle n;

    ros::Subscriber sub = n.subscribe("imu/data", 100, IMUCallback);

    ros::spin();

    return 0;
}

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

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

相关文章

嫦娥六号平安回家,Smartbi非常荣幸参与中国航天项目

“小时不识月&#xff0c;呼作白玉盘。”李白的这句诗&#xff0c;承载了古人对月亮的美好想象与纯真童趣。今天&#xff0c;当我们仰望夜空&#xff0c;那轮明月不仅是诗词中的意象&#xff0c;更是科学探索的目标和梦想的寄托。 2024年6月25日14时07分&#xff0c;嫦娥六号返…

安全与加密常识(0)安全与加密概述

文章目录 一、信息安全的基本概念二、加密技术概述三、常见的安全协议和实践四、加密的挑战与应对 在数字时代&#xff0c;信息安全和加密已成为保护个人和企业数据不受侵犯的关键技术。本文将探讨信息安全的基础、加密的基本原理&#xff0c;以及实用的保护措施&#xff0c;以…

Python中相关软件安装

1. python安装 1.下载地址 https://www.python.org/downloads/2.选择安装版本 1. Anaconda安装 安装地址 -- 清华大学镜像站点 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/查看anaconda是否安装成功 2.conda安装好后&#xff0c;将镜像源修改为清华大学的镜像…

知识库在AI大模型中的使用流程

大模型知识库的使用流程通常包括以下关键步骤&#xff0c;大模型知识库的使用流程需要跨学科的知识和技能&#xff0c;包括自然语言处理、数据库管理、软件工程等。同时&#xff0c;也需要关注用户体验、性能优化、安全保护等方面&#xff0c;以提供高质量的知识服务。北京木奇…

封装了一个iOS滚动厨窗效果

效果图 背景 我们要实现如图的厨窗效果&#xff0c;不能通过在tableView底部添加一个背景图片的方式&#xff0c;因为这需要修改整个tableView的背景色为透明&#xff0c;影响到的范围太大&#xff0c;只能将这个效果局限在这个cell 中&#xff0c;然后通过监听tableView的滚动…

昇思MindSpore学习笔记3--张量 Tensor

一、张量Tensor概念 矢量、标量和其他张量的计算函数&#xff0c;有内积、外积、线性映射以及笛卡儿积等 张量坐标在 n 维空间内&#xff0c;有 nr 个分量 每个分量都是坐标的函数,变换时每个坐标分量都按规则作线性变换 张量是一种特殊的数据结构&#xff0c;类似于数组和…

npm安装包报错解决

目录 一&#xff1a;问题回顾 二:问题分析 三&#xff1a;npm降级或者升级 四&#xff1a;npm和node js 关系 一&#xff1a;问题回顾 今天在本地部署一个vue开发的项目&#xff0c;需要在本地看下运行情况&#xff0c;按照常规的操作就是在网站根目录运行npm install 安装…

如何制作鼠标悬浮后伸缩的搜索框

引言 许多博客都在使用的伸缩搜索框制作教程 成品展示&#xff08;颜色自行搭配&#xff09; 初步布局 居中盒子&&初始化样式 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewpo…

Nuxt3 的生命周期和钩子函数(五)

title: Nuxt3 的生命周期和钩子函数&#xff08;五&#xff09; date: 2024/6/29 updated: 2024/6/29 author: cmdragon excerpt: 摘要&#xff1a;本文详细介绍了Nuxt3中的六个核心生命周期钩子及其用法&#xff0c;包括build:done、build:manifest、builder:generateApp、…

[oeasy]python021_赛博宝剑铭文大赏_宝剑上的铭文_特殊符号和宝物

继续运行 &#x1f94b; 回忆上次内容 上次修改了 程序 将 石中剑变成了 红色 爱之大剑 可以 让宝剑 具有 更多铭文符号 和 颜色 吗&#xff1f;&#x1f914; 铭文 亚瑟王 从石头中 取得宝剑 说明 不列颠科技从石器时代 进入了 青铜时代 第一把 Caliburn 断裂 第二把 湖中仙…

恢复的实现技术-日志和数据转储

一、引言 在系统正常运行的情况下&#xff0c;事务处理的恢复机制应采取某些技术措施为恢复做好相应的准备&#xff0c;保证在系统发生故障后&#xff0c;能将数据库从一个不一致的错误状态恢复到一个一致性状态 恢复技术主要包括 生成一个数据库日志&#xff0c;来记录系统中…

iOS开发中用到的自定义UI库

文章目录 前言cell 左右滑动菜单日历组件仿QQ 侧滑抽屉仿探探、陌陌的卡牌滑动库头部缩放视图自定义UITabbar刮刮乐广告横幅 前言 本文中的UI组件&#xff0c;是作者在移动应用开发中都用到过的。 确实&#xff0c;找到对的三方库可以快速帮助我们构建App, 极大程度上提高了生…

ESP32-C2模组数据透传模式配置详细教程

文章目录 1. 背景2. 关键步骤2.1 烧录AT指令固件2.2 配置透传模式2.3 如何退出透传模式重新配置3. 思考1. 背景 最近做的项目中,有蓝牙+WIFI的数据透传的需求,即系统A和系统B之间的通讯通过无线的方式,其实在实际项目中有很多这种场景比如无线调试手柄、无线数据终端、无线…

c进阶篇(一):数据的存储

1.数据类型介绍 char // 字符数据类型 short // 短整型 int // 整形 long // 长整型 long long // 更长的整形 float // 单精度浮点数 double // 双精度浮点数 1.1整形家族&#xff1a; char unsigned char signed char …

Linux 生产消费者模型

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux初窥门径⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Linux知识   &#x1f51d; 前言 1. 生产消费者模型 1.1 什么是生产消…

stm32学习笔记---ADC模数转换器(代码部分)AD单通道/多通道

目录 第一个代码&#xff1a;AD单通道 ADC初始化步骤 ADC相关的库函数 RCC_ADCCLKConfig 三个初始化相关函数 ADC_Cmd ADC_DMACmd ADC_ITConfig 四个校准相关函数 ADC_SoftwareStartConvCmd ADC_GetSoftwareStartConvStatus ADC_GetFlagStatus ADC_RegularChannel…

探索 Electron:将 Web 技术带入桌面应用

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

iOS17系统适配

iOS17 新功能 文章目录 iOS17 新功能iOS17支持哪几款机型Xcode15新特性iOS17-开发适配指南 横屏待机 在iOS 17中&#xff0c;还带来了横屏待机功能&#xff0c;苹果将这个新功能命名为“Standby”模式&#xff0c;为 iPhone 带来了全新的玩法。iPhone启用之后&#xff0c;默认情…

文件加密|电脑文件夹怎么设置密码?5个文件加密软件,新手必看!

电脑文件夹怎么设置密码&#xff1f;您是否希望更好地在电脑上保护您的个人或敏感文件&#xff1f;设置电脑文件夹密码是一种简单而有效的方式来确保你的隐私不被侵犯。通过使用文件加密软件&#xff0c;您可以轻松地为您的文件和文件夹设置密码保护。因此&#xff0c;本文将介…

快速应用开发(RAD):加速软件开发的关键方法

目录 前言1. 快速应用开发的概念1.1 什么是快速应用开发&#xff1f;1.2 RAD与传统开发方法的对比 2. 快速应用开发的实施步骤2.1 需求分析与规划2.2 快速原型开发2.3 用户评估与反馈2.4 迭代开发与改进2.5 最终交付与维护 3. 快速应用开发的优点与应用场景3.1 优点3.2 应用场景…