Moveit!入门——古月居机械臂开发笔记(一)

2023-05-16

Moveit!入门——古月居机械臂开发笔记(一)

  • 引言
  • Moveit!与机械臂控制
    • 1、创作机械臂模型
    • 2、生成配置文件
    • 3、如何使用Moveit!实现机械臂仿真(gazebo)
      • 完善模型
      • 在gazebo中加载机械臂模型
      • ros_control
      • 配置并加载控制器
      • 最终使用Moveit!
    • 4、通过Moveit!控制机械臂运动(用户接口:C++、python)
      • 编程模式
      • 几种空间运动
      • 轨迹约束
      • 轨迹修改
  • 后记

引言

在上一篇完成场景搭建后觉得自己对Moveit!还不是很熟悉,找了b站上古月居的机械臂开发原理的视频进行学习。教程分为三部分:

  1. Moveit!和机械臂控制
  2. ROS机械臂开发_机器视觉与物体抓取
  3. ROS机械臂开发_机械臂开发实例
     

Moveit!与机械臂控制

 

1、创作机械臂模型

       首先是写自己的urdf机械臂模型文件,主要包括<-link>连杆和连接两个连杆的<-joint>关节(有6中连接类型)。通常还是xacro格式,因为xacro中可以有一些编程语句,变量运算等。如果用ur等机械臂的话就可以使用其现成的模型文件。

       有了模型文件后,可以通过rviz来查看该模型——将.xacro文件加载到robot_description的变量中(因为rviz中RobotModel插件订阅了robot_description),启动joint_state_publisherrobot_state_publisher节点(ROS提供)。

<launch>
  <arg name="gui" default="true" />
  <arg name="robot_desciption" default="$(find xacro)/xacro --inoder '$(find ur5_single_arm_turfs)/urdf/ur5_single_arm.urdf.xacro'"/>
  <arg name="rvizconfig" default="$(find ur5_single_arm_turfs)/launch/ur5_single_arm_rviz.rviz" />
  <param name="use_gui" value="$(arg gui)"/>
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" /> 
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />
</launch>

joint_state_publisher:关节状态发布器。如六轴机械臂,每一个轴有自己的一个位置角度,这六个角度就是关节状态。即将关节状态通过Topic发布出来。
robot_state_publisher:订阅发布的关节状态Topic,将六个角度通过TF发布出来。可以理解为正向运动学(已知六个轴的角度参数,求六个轴的空间位置)
其中rvizconfig中.rviz文件是rviz中保存的参数文件,可在第一次设置机械臂各种参数(如选择fix_frame、添加RobotModel插件等)
 

2、生成配置文件

       同样,ur等机械臂已经完成了配置,在moveit_config文件夹中。如果是自己做的机械臂,通过以下步骤:

roslaunch moveit_setup_assistant setup_assistant.launch

主要步骤

  1. 选择模型文件
  2. 自碰撞检测
  3. 虚拟关节,机械臂与世界坐标系的关系,主要用于移动机器人
  4. 设置机械臂规划组(PlanningGroups)。通常为两个部分:六轴、夹爪。还需要设置运动学求解器(Moveit默认的KDL,可以更换为效果更好的)
  5. 预定义机械臂位姿,便于编写程序直接调用
  6. 终端夹具配置,名称、坐标系
  7. Passive Joints,设置某个关节无需进行计算,一般不设置
  8. 输出配置文件(可在.srdf文件中查看配置结果)

       可以运行文件夹中demo.launch尝试是否配置成功
 

3、如何使用Moveit!实现机械臂仿真(gazebo)

       将创建的六轴机械臂放在gazebo环境中,通过Moveit!来控制机械臂做移动。我目前认知,只有在gazebo中仿真才需要完善模型等操作,而真实机械臂是不需要的。

完善模型

       同样,ur等机械臂已经完成了该步骤,如果需要自己设置,则参考以下步骤:

  1. 在.xacro中完善一些描述信息——惯性参数<-inertial>和碰撞属性<-collision>(均为每一个link需要设置的)
  2. 为link添加gazebo标签——如设置link颜色,在.xacro中设置的颜色在rviz中能够看到,但在gazebo中显示不出来(gazebo有自己的颜色显示系统)。还可以设置摩擦系统等物理仿真引擎(如在gazebo中添加其他仿真模型物体需要设置摩擦参数,材质等等)。ur中文件位置为ur_description/urdf/ur.gazebo.xacro
<gazebo reference="base_link">
	<material>Gazebo/White</material>
</gazebo>
  1. 为joint添加传动装置——可以简单理解为给机械臂装电机。(传动)Transmissions就是机器人的传动系统,机器人每个需要运动的关节都需要配置相应的Transmission,其通常在urdf文件中直接添加。如ur中在ur5.urdf.xacro文件中有:
<xacro:include filename="$(find ur_description)/urdf/ur.transmission.xacro" />

       该部分涉及ros_control的知识,可以参考https://www.guyuehome.com/890。如要自己写该部分,以elbow_joint为例,其他joint几乎一样:

<transmission name="${prefix}elbow_trans">
	<type>transmission_interface/SimpleTransmission</type>
	<joint name="${prefix}elbow_joint">
		<hardware_interface>hardware_interface/PositionJointInterface</hardware_interface>
	</joint>
	<actuator name="${prefix}elbow_motor">
		<machanicalReduction>1</machanicalReduction>
	</actuator>
</transmission>
  1. 添加gazebo控制器插件。在ur中,ur_description/urdf/ur5_robot.urdf.xacro中有include进同目录下的common.gazebo.xacro。在common.gazebo.xacro有:
<gazebo>
	<plugin name="ros_control" filename="libgazebo_ros_control.so">
	</plugin>
</gazebo>

 

在gazebo中加载机械臂模型

<?xml version="1.0"?>
<launch>
  <arg name="paused" default="true"/>
  <arg name="gui" default="true"/>
  <arg name="sim" default="true" />
  <arg name="debug" default="false"/>
  <!-- startup simulated world -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <!--arg name="world_name" default="worlds/empty.world"/-->
    <arg name="world_name" default="$(find ur5_single_arm_tufts)/worlds/ur5_cubes.world"/>
    <arg name="paused" value="$(arg paused)"/>
    <arg name="gui" value="$(arg gui)"/>
  </include>

  <!-- send robot urdf to param server -->
  <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find ur5_single_arm_tufts)/urdf/ur5_single_arm.urdf.xacro'"/>

  <node name="spawn_gazebo_model" pkg="gazebo_ros" type="spawn_model"
        args="-urdf -param robot_description -model robot -z 0.594 
              -J shoulder_lift_joint -2.0
              -J elbow_joint 1.0" 
        output="screen" />
  <!-- 同时设置了初始位姿 -->
</launch>

       到这一步为止,运行上面代码的launch文件,可以在gazebo中看到机械臂模型,但是无法通过GUI rviz、C++、python等接口去发布信息控制机械臂运动。要控制机械臂运动还需要完善ros_control控制器。
 

ros_control

参考https://www.guyuehome.com/890
在这里插入图片描述
在这里插入图片描述
 

配置并加载控制器

       在ur中,ur_gazebo/controller/arm_controller_ur5.yaml中有进行配置。

注:此时从步骤上分析/arm_controller_ur5.yaml中仅有joint_group_position_controller,并无arm_controller(其中的JointTrajectoryController为Moveit!和机械臂的接口,参考下面重要的图)

arm_controller:
  type: position_controllers/JointTrajectoryController
  joints:
     - shoulder_pan_joint
     - shoulder_lift_joint
     - elbow_joint
     - wrist_1_joint
     - wrist_2_joint
     - wrist_3_joint
  constraints:
      goal_time: 0.6
      stopped_velocity_tolerance: 0.05
      shoulder_pan_joint: {trajectory: 0.1, goal: 0.1}
      shoulder_lift_joint: {trajectory: 0.1, goal: 0.1}
      elbow_joint: {trajectory: 0.1, goal: 0.1}
      wrist_1_joint: {trajectory: 0.1, goal: 0.1}
      wrist_2_joint: {trajectory: 0.1, goal: 0.1}
      wrist_3_joint: {trajectory: 0.1, goal: 0.1}
  stop_trajectory_duration: 0.5
  state_publish_rate:  25
  action_monitor_rate: 10
joint_group_position_controller:
  type: position_controllers/JointGroupPositionController
  joints:
     - shoulder_pan_joint
     - shoulder_lift_joint
     - elbow_joint
     - wrist_1_joint
     - wrist_2_joint
     - wrist_3_joint`在这里插入代码片`

       然后在launch文件中:

<rosparam file="$(find ur_gazebo)/controller/arm_controller_ur5.yaml" command="load"/>
<rosparam file="$(find robotiq_85_gazebo)/controller/gripper_controller_robotiq.yaml" command="load"/>
<node name="arm_controller_spawner" pkg="controller_manager" type="controller_manager" args="spawn arm_controller gripper" respawn="false" output="screen"/>

(此时还没有joint_state_controller[等价于joint_state_publisher]和robot_state_publisher),所以在最终的launch文件中有:

<include file="$(find ur_gazebo)/launch/controller_utils.launch"/>
<?xml version="1.0"?>
<launch>
  <!-- Robot state publisher -->
  <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher">
    <param name="publish_frequency" type="double" value="50.0" />
    <param name="tf_prefix" type="string" value="" />
  </node>

  <!-- Fake Calibration -->
  <node pkg="rostopic" type="rostopic" name="fake_joint_calibration"
        args="pub /calibrated std_msgs/Bool true" />
  
  <!-- joint_state_controller -->
  <rosparam file="$(find ur_gazebo)/controller/joint_state_controller.yaml" command="load"/>
  <node name="joint_state_controller_spawner" pkg="controller_manager" type="controller_manager" args="spawn joint_state_controller" respawn="false" output="screen"/>
</launch>

       joint_state_controller.yaml文件中为:

joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50  

       此时相当于有三个控制器——joint_state_controller、joint_group_position_controller:(包含六个关节的position)、gripper,还未包含arm_controller中的JointTrajectoryController。/joint_states话题可以查看机械臂状态。

 

最终使用Moveit!

       以上虽然让机械臂在gazebo中动起来了,但是到刚才的运动为止,没有任何Moveit!的操作。那Moveit!给我们的究竟是什么呢?——关节轨迹(JointTrajectory)

       刚才配置的PositionController为针对每一个关节的输入(应该是位置?),该输入并不是轨迹。

       如何将机器人控制Moveit!连接在一起,即Moveit!的输出和机器人的输入之间接口是什么。通过Action通信机制——FollowJointTrajectory传递Trajectory数据P[] V[] A[] T(位置、速度、角度、时间)组合起来描述一系列轨迹点。follow_joint_trajectory是MoveIt!最终运动规划发布的action消息,由机器人控制器端接收该消息后控制机器人完成运动。在rostopic list中,可以找到follow_joint_trajectory,由仿真机器人的控制器插件订阅。
       下图十分重要,解释了Moveit!最终输出的为轨迹点,以及我们使用Moveit!需要配置的controller
在这里插入图片描述
       此时从步骤上来说,即完成了ur_gazebo/controller/arm_controller_ur5.yaml中有关arm_controller的配置。

       总的来说,此时完成了上图中插座端的JointTrajectoryControllerJointStateController。现在gazebo可以接收轨迹,反馈状态,接下来则需要完成插头端Moveit!的Controller配置FollowJointTrajectory(ros中的Action),以便将轨迹发布出去。

       在ur中,ur5_moveit_config/config/controllers.yaml中即完成了该配置,同时在ur5_moveit_config/launch/ur5_moveit_controller_manager.launch.xml中加载了该参数包。

controller_list:
  - name: ""
    action_ns: follow_joint_trajectory
    type: FollowJointTrajectory
    joints:
      - shoulder_pan_joint
      - shoulder_lift_joint
      - elbow_joint
      - wrist_1_joint
      - wrist_2_joint
      - wrist_3_joint

       接下来即可定义最上层的launch文件,将各类参数加载进来:
在这里插入图片描述
       这一部分的套路就是先写controller的yaml参数文件,再在launch文件中rosparam load,最后通过controller_manager pkg载入。

 

4、通过Moveit!控制机械臂运动(用户接口:C++、python)

       通过编程控制机械臂做运动。
在这里插入图片描述
       实际上通过编程接口控制机械臂运动经过了以下四步:
在这里插入图片描述
 

编程模式

       Moveit!中编程控制机械臂的主要步骤:

  1. 连接控制需要的规划组(如arm组或gripper组)
  2. 设置目标位姿(关节空间或笛卡尔空间)
  3. 设置运动约束(可选,如夹水杯,保持水杯向上)
  4. 使用Moveit!规划一条到达目标的轨迹
  5. 修改轨迹(如速度等参数)
  6. 执行规划出的轨迹

       主要通过学习Moveit!官方教程来学习相应的API功能。
 

几种空间运动

设置关节角度:主要API:

  1. 创建规划组的控制对象
  2. 设置关节空间运动的目标位姿
  3. 完成规划并控制机械臂完成运动

在这里插入图片描述
设置终端位姿:主要API:

  1. 创建规划组的控制对象
  2. 获取机器人的终端Link名称
  3. 设置目标位姿对应的参考坐标系和起始、终点
  4. 完成规划与运动
    在这里插入图片描述

笛卡尔路径运动
在这里插入图片描述
       plan:规划出来的运动轨迹
       fraction:描述规划成功的路径在给定路点列表中的覆盖率,如果fraction小于1,说明给定的路点列表没办法完整规划路径。
 

轨迹约束

       给轨迹加约束,如夹杯子,希望杯子保持朝上,则终端需要保持朝上。
       Moveit!中运动规划的流程如下:
在这里插入图片描述
       从左到右:

  1. 运动规划请求:让机械臂从A到B,B即目标值
  2. 适配器组:检查机械臂初始状态,设置一些约束条件
    在这里插入图片描述
  3. 运动规划器:调用OMPL中算法,计算轨迹。此时得到的轨迹只有P[],没有V[],A[],t。
  4. 适配器组:添加速度、加速度、时间参数
  5. 运动规划应答:即为FollowJointTrajectory中要发布的轨迹
    在这里插入图片描述
     

轨迹修改

       修改已经plan好的轨迹,也可以理解为自己加一些“约束”,通过修改结构体(轨迹)中的数据。需要自己事先实现相应的API。
在这里插入图片描述

后记

       以上即是博主结合课程和ur5机械臂的理解笔记,如有不当之处还望各位同行大佬多多指教。单Moveit!这一部分感觉还有运动学插件、规划场景没有讲到,接下来应该就是运动学插件、物体抓取与加入视觉了。

ps: 写了两天,第二天写完的时候都发布了,发现发布的只有第一天的内容,又要重新写,气死了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Moveit!入门——古月居机械臂开发笔记(一) 的相关文章

  • XCOM2.0接收数据为0

    新装系统后 xff0c 串口助手Xcom2 0版本 xff0c 使用FT232接受到的数据全是0 xff0c FT232已经有驱动 xff0c 经过多出测试 xff0c 需要更新FTDI的官网驱动 xff0c 并重启 xff0c 问题解决
  • PyQt(Python+Qt)学习随笔:Action功能详解及Designer中的操作方法

    老猿Python博文目录老猿Python博客地址 一 引言 Qt Designer中的部件栏并没Action相关的部件 xff0c Action可以在右侧的Action Editor中编辑 xff0c 如图 xff1a 如果没有出现Acti
  • 鸿蒙最新功能及承载设备详解:HarmonyOS 2及华为全场景新品发布会全纪录

    6月2日 xff0c 华为联手CSDN直播了 HarmonyOS 2及华为全场景新品发布会 xff0c 老猿全程观看直播 xff0c 并进行了回看 xff0c 力争将发布会的核心内容在本文中概要性地呈现 一 一生万物 万物归一 首先是华为消
  • 构建VisualStudio2019+OpenCV4.3的C++ windows编译环境

    一 引言 最近在读源代码研究CLAHE的算法 xff0c 但好久没学习C 43 43 了 xff0c 发现部分代码难以理解 xff0c 因此最后下决心装一个C 43 43 编译器 下载OpenCV源码 xff0c 这样碰到疑难问题就可以实际
  • 关于C++集合操作赋值和集合间操作的结果集合的疑问

    一 关于集合的疑问 最近对C 43 43 语言的集合操作比较感兴趣 xff0c 看了好友博主CP猫介绍的 C 43 43 中集合set的常用操作 xff0c 在使用时有3个疑问 xff1a 集合的变量赋值能否直接将一个集合实例赋值个另一个集
  • 如何使用Docker暴露多个端口?

    本文翻译自 xff1a How can I expose more than 1 port with Docker So I have 3 ports that should be exposed to the machine 39 s i
  • 人工智能基础概念1:模型、拟合、最大似然估计、似然函数、线性回归、sigmoid函数、逻辑回归

    一 模型 拟合 xff08 fitting xff09 和过拟合 xff08 overfitting xff09 人工智能中的模型 xff08 Artificial Intelligence Model xff09 指的是一些算法和数学模型
  • 中国移动提出的ABCDNETS和DSSN数联网技术介绍

    一 引言 在2023年4月14日 xff0c 中国移动召开 数据要素流通与治理产业高峰论坛上 xff0c 中国移动发布了 数联网 xff08 DSSN xff09 白皮书 xff0c 同时发布了全球首创的数联网 DSSN 服务平台等产品 x
  • Python循环语句(while循环、for循环)

    Python循环语句 一 while循环二 for语句三 range 函数四 break 和 continue 语句五 pass语句 Python循环语句主要有while循环和for循环 xff0c Python 循环语句的控制结构图如下所
  • 深度学习笔记一:深度学习环境的搭建

    首先需要下载anaconda xff08 官方网站下载 xff09 一路选择next即可 这里我没有选择添加环境变量 xff0c 如果有需要 xff0c 后期可以手动添加 xff0c 这里可以根据自己情况选择 安装完成后 xff0c 从wi
  • HAN论文模型代码复现与重构

    论文简介 本文主要介绍CMU在2016年发表在ACL的一篇论文 xff1a Hierarchical Attention Networks for Document Classification及其代码复现 该论文是用于文档级情感分类 xf
  • Http Digest认证协议

    http blog csdn net htjoy1202 article details 7067287 其认证的基本框架为挑战认证的结构 xff0c 如下图所示 xff1a xfeff xfeff 1 客户端希望取到服务器上的某个资源 x
  • 【系统分析师之路】嵌入式系统章节错题集锦

    系统分析师之路 嵌入式系统章节错题集锦 系分章节错题集第01题 xff1a 红色 01 雷达设计人员在设计数字信号处理单元时 xff0c 其处理器普遍采用DSP芯片 xff08 比如 xff1a TI公司的TMS320C63xx xff09
  • 【软工】程序编码

    目录 前言正文 程序设计语言 分类 选择原则 程序编码总原则 好程序的标准 结构化程序设计 主要内容 主要原则 程序设计风格 源程序文档化 数据说明 语句结构 输入输出方法 程序设计质量评价 正确性结构清晰性易修改性 易读性 简单性 程序复
  • TPM1.2到TPM 2.0的变化

    原文地址 xff1a http www vonwei com mod 61 pad amp act 61 view amp id 61 11 TPM 1 2规范主要面向PC平台 xff0c 其103版本在2009年被接受为ISO标准 xff
  • 关于Cmake与CmakeLists(一)--背景,须知,示例

    一 背景及须知 1 背景 xff1a VS2019与VS2010在编写程序时都是创建了一个工程 xff0c 然后直接打开 sln即可 但是vscode仅仅是一个编辑器 xff0c 打开之后只有 c或者 cpp文件 xff0c 故需要手动编译
  • webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案——第五课

    webgl three js 实现室内定位 楼宇bim 实时定位三维可视化解决方案 第五课 参考文章 xff1a xff08 1 xff09 webgl three js 实现室内定位 楼宇bim 实时定位三维可视化解决方案 第五课 xff
  • Linux虚拟机在线扩容lvm类型root分区

    目录 Linux虚拟机在线扩容lvm类型root分区写在前面正文写在后面 Linux虚拟机在线扩容lvm类型root分区 写在前面 这是我在CSDN上的第一篇文章 作为一个半江湖的IT人 xff0c 这些年来也在CSDN受益很多 今天是20
  • 无vCenter创建vSAN集群

    无vCenter创建vSAN集群 最近仍有朋友在问题 xff0c vCenter如果 挂了 xff0c vSAN还能正常运行吗 xff1f 这个小文通过手动创建vSAN集群的方式来解答下这个问题吧 xff08 生产环境慎用 xff01 xf
  • 记一次mdadm软raid1升级容量

    MDRaid 2块4TB做了软RAID1 xff0c 需要升级成2块8TB盘 查看磁盘信息 xff0c SerialNumber等会儿会用到 xff0c 防止换错盘 span class token function sudo span h

随机推荐

  • [简洁版]youtube-dl下载命令

    简介 YouTube dl是python上的pip模块 xff08 开源 xff09 xff0c 可以用来下载YouTube Bilibili等多个平台的视频 音频文件 xff0c 可谓是居家旅行必备小工具 本文主要介绍一些常用的youtu
  • [简版]VMware强大的管理工具-PowerCLI

    一 PowerCLI介绍 什么是 PowerCLI PowerCLI 是一个命令行工具 xff0c 可以用于自动化vSphere管理 xff0c 包括网络 存储 虚拟机以及其他很多功能 PowerCLI包含超过700个命令 要安装Power
  • [简版]使用PowerCLI自定义vSphere ISO安装镜像

    一 什么情况下要自定义ISO镜像 一般来说 xff0c 对于DELL Lenovo HPE这类主流的服务器厂商 xff0c VMware官方vSphere ISO镜像或者官网的第三方客制镜像 xff08 由服务器厂商提供的封装镜像 xff0
  • [简版] 关于vSphere漏洞-OpenSLP

    一 前言 近期vSphere OpenSLP漏洞在野利用的新闻频频被爆出来 xff0c 大伙儿非常关注 由于vSphere虚拟化客户之广泛 xff0c 很多朋友都表达了自己的焦虑 xff0c 同时也会担心自己管理的vSphere虚拟化平台是
  • [简版] Linux搭建SAMBA文件共享服务

    SMB服务搭建 更多参数含义参考链接 常用配置 安装samba span class token comment Ubuntu span span class token function sudo span span class toke
  • STM32 HAL库详解

    STM32 HAL库整体总结 STM32 之二 HAL库详解 及 手动移植 本篇博客是对以上参考资源的一个二次总结与整理 1 HAL库文件结构 对于开发人员而言 xff0c 首先要清楚 HAL 库的文件结构 根据文件类型可认为以下两大类 x
  • STM32 HAL库学习(四):DMA之串口空闲中断

    STM32CubeMX 配置实现参考这里 1 串口空闲中断 1 1 UART DMA方式接收数据 STM32串口使用DMA方式接收数据可以减小CPU的开销 对于接收定长数据 xff0c 可以将DMA接收缓冲区的长度设定为待接收数据的长度 x
  • Android Studio 启动模拟器出现“Timed out after 300seconds waiting for emulator to come online“解决方案

    Android Studio 启动模拟器出现 34 Timed out after 300seconds waiting for emulator to come online 34 解决方案 参考文章 xff1a xff08 1 xff0
  • 结构体中的位定义

    1 结构体位定义 在工作中 xff0c 经常遇到按位 xff08 bit xff09 定义结构体 的情况 由于一个字节有8个位 xff0c 这时 xff0c 程序员往往对bit的位置产生困惑 现在给出2个例子 xff0c 来说明位的定义次序
  • 蓝牙基础(三):蓝牙协议栈总体认知

    蓝牙基础 xff08 三 xff09 xff1a 蓝牙协议栈总体认知 0 前言 初入门经典蓝牙学习 xff0c 网上资料参差不齐 xff0c 本博客旨在整理自己的一些总结内容 xff0c 建立整体功能认识 xff0c 以便后续深入学习 1
  • FreeRTOS学习(四)任务调度与切换

    文章目录 1 任务调度2 任务切换2 1 SVC 和 PendSV2 2 上下文2 3 切换场景2 4 PendSV Handler 3 总结 1 任务调度 在建立完任务后紧接着调用任务调度函数 xff0c 便会使系统运行起来 span c
  • FreeRTOS学习(五)队列与信号量

    文章目录 1 队列1 1 队列特性1 2 队列创建1 2 1 接口函数1 2 2 内存占用1 2 3 创建过程分析 1 3 入队与出队1 3 1 队列项入队1 3 1 队列项出队 2 信号量2 1 二值信号量2 2 计数型信号量2 3 互斥
  • FreeRTOS学习(六)时间管理

    文章目录 1 延时函数1 1 vTaskDelay 1 2 vTaskDelayUntil 1 3 系统时钟节拍 2 软件定时器2 1 定时器概述2 2 定时器 API 3 总结 1 延时函数 当任务需要调用延时函数延时时 xff0c 任务
  • C语言 sscanf库函数

    目录 1 函数描述2 函数应用2 1 基础应用2 2 高级应用 1 函数描述 xff08 1 xff09 函数功能 xff1a 通常被用来解析并转换字符串 xff0c 从str指定的字符串读取数据 xff0c 并根据参数format字符串来
  • C语言 文件读写

    目录 1 文件打开与关闭1 1 打开文件 fopen 1 2 关闭文件 fclose 2 读取文件2 1 fgetc 2 2 fgets 2 3 fscanf 3 写入文件3 1 fputc 3 2 fputs 3 3 fprintf 1
  • C语言 条件编译

    目录 1 if elif else endif 2 ifdef else endif 3 ifndef else endif 4 三者区别 根据不同情况编译不同代码 产生不同目标文件的机制 xff0c 称为条件编译 条件编译是预处理程序的功
  • yolo 学习系列(三):训练参数与网络参数

    yolo 学习系列 xff08 三 xff09 xff1a 训练参数与网络参数 手把手教你做目标检测 xff08 YOLO SSD xff09 视频链接 1 训练参数 博主在使用 yolov2 tiny voc 训练 人 这一类目标物体时
  • Caffe 学习系列(七):MobileNet-YOLO 安装与训练

    Caffe 学习系列 xff08 七 xff09 xff1a MobileNet YOLO 安装与训练 基于darknet实现mobilenet 基于darknet框架实现DepthwiseConvolutional层 深度学习 xff08
  • 完美解决api-ms-win-crt-runtime-l1-1-0.dll 丢失问题

    完美解决api ms win crt runtime l1 1 0 dll 丢失问题 参考文章 xff1a xff08 1 xff09 完美解决api ms win crt runtime l1 1 0 dll 丢失问题 xff08 2 x
  • Moveit!入门——古月居机械臂开发笔记(一)

    Moveit 入门 古月居机械臂开发笔记 xff08 一 xff09 引言Moveit xff01 与机械臂控制1 创作机械臂模型2 生成配置文件3 如何使用Moveit xff01 实现机械臂仿真 xff08 gazebo xff09 完