ROS与GAZEBO实时硬件仿真(4)——深入理解与总结

2023-05-16

声明:本博客是对博主无人的回忆所写的ROS与GAZEBO实时硬件仿真系列文章的自我理解与总结,所写内容是基于该博主的三篇博文的,如果有幸被人参考,建议先看完该博主的三篇文章再来看这篇文章。三篇文章的链接已经在下方贴出。这几篇文章我反复看了好几遍,对于新人理解ROS与GAZEBO是怎么联系起来的真的非常有帮助,在此谢过!

其次,本人也是刚入门不久的小白,里面所有的内容都是我自己的主观理解,肯定会有失偏颇或者直接就是错误的。希望大家发现错误以后可以留言或者私信我,共同进步!

下面,引用起来的内容为从原博文出摘取的内容,加粗显示的为我个人的理解。

篇一 官方图

两天下来,对这张图已经从一开始的一脸蒙比到现在可以基本了解里面的结构框架与机制啦。确实是一张越看越明白的图。

把大象装进冰箱的第一步——urdf文件

该文件的主要功能就是描述机器人各个部分(link)与关节(joint)的属性。

简单的一个例子就是这样:

<?xml version="1.0"?>
<robot name="rbo" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <link name="car_link">

        <visual>
            <geometry>
                <box size="2.0 1.0 0.5"/>
            </geometry>
        </visual>

        <collision>
            <geometry>
                <box size="2.0 1.0 0.5"/>
            </geometry>
        </collision>
    </link>
</robot>

运行以下命令就可以在rviz中看到

roslaunch urdf_tutorial display.launch model:=myrobot.urdf.xacro

如果出现错误提示:No such file or directory: myrobot.urdf.xacro,那说明找不到此文件。解决方案有两种:
1、使用以下命令:
roslaunch urdf_tutorial display.launch model:='$(find myrobot_description)/urdf/myrobot.urdf.xacro'
2、将当前工作目录定位到你存放该文件的目录

link包含的元素

1、visual标签:这表示着我们是否可以在图形界面上观察到这个link,没有的话就观察不到,主要包含geometry标签
2、collision标签:这表示着传感器(主要指激光等投射型的传感器)是否可以在物理引擎上检测到这个link,同时标志着是否会与别的link进行碰撞检测,也主要包含geometry标签
3、inertial标签:这表示着物理引擎是否能够感受到link的存在,主要包含3个标签:
origin:link重心的位置
mass:link的重量
inertia:link的旋转惯量

在gazebo中,这个标签却直接决定了这个link能否被看到!其中的原因很重要,我一定要另起一行说三遍!
在ros中,机器人节点的驱动靠的是TF,而在gazebo中,机器人节点的驱动主要靠物理引擎!!!
在ros中,机器人节点的驱动靠的是TF,而在gazebo中,机器人节点的驱动主要靠物理引擎!!!
在ros中,机器人节点的驱动靠的是TF,而在gazebo中,机器人节点的驱动主要靠物理引擎!!!

在ros中,你想改变两个link的相对位置写个node修改TF就行了!但是,在gazebo中,你想改变两个link的相对位置必须要有物理层面的输出

没有inertial标签的link在gazebo中是完全看不到的

Joint——ros的TF与gazebo的连接

在ros中,joint_state_publisher这个节点会通过joint来了解到每个link之间的连接关系,从而根据一个link值推算出所有的link的TF状态

类似与link,要想让joint工作,你必须声明它所必须的标签,主要包括下面的主要标签:
1.name:标签的名称
2.type:指明这个标签的类型
3.parent:这个关节的一端,称为父端
4.child:这个关节的另一端,称为子端
5.origin:父端与子端的初始transform,例如相机的坐标系与底盘的坐标系方向相同,但是在x方向上差了0.1m,那么就在这个标签上填充上相应的值,该标签默认的值是两个质心是完全重合的。
6.axes:旋转轴,type标签里面反复提到的旋转轴就是这个标签,它指示了绕什么轴进行旋转,例如绕父节点的z轴旋转,那么该标签的值就为xyz=“0 0 1”
7.limit:有限值旋转类型必备标签,指示旋转所能到到的上下限。 实际上,joint还是有很多标签的,这里列举了最常用的几个,实际上,只有前4个标签是必须的,其他的标签是要随着你的要求进而确定的。

base_link这个老大哥,通常情况下,因为机器人都是有高度的,因此base_link一般都是与机器人最下方的link进行固定连接,同时高度上相差合适的高度

个人理解:也就是说base_link在rviz中是必要的,通过它才能知道机器人放在哪,当然可能还有其他的方式,比如odom?
但是在gazebo中测试了一下,没有下面的定义也可以进行仿真

    <!-- base_link -->
    <link name="base_link"/>
    <joint name="base_link_car" type="fixed">
        <origin xyz="0.0 0.0 ${wheel_radius}" rpy="0.0 0.0 0.0"/>
        <parent link="base_link"/>
        <child link="car_link"/>
    </joint>

如果你使用gazebo打开的话,就会看到比较有趣的地方,由于重力的作用,一边重重的掉在了地上

display.launch

<launch>

  <arg name="model" default="$(find urdf_tutorial)/urdf/01-myfirst.urdf"/>
  <arg name="gui" default="true" />
  <arg name="rvizconfig" default="$(find urdf_tutorial)/rviz/urdf.rviz" />

  <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />
  <param name="use_gui" value="$(arg gui)"/>

  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />

</launch>

gazebo.launch

<launch>

  <!-- these are the arguments you can pass this launch file, for example paused:=true -->
  <arg name="paused" default="false"/>
  <arg name="use_sim_time" default="true"/>
  <arg name="gui" default="true"/>
  <arg name="headless" default="false"/>
  <arg name="debug" default="false"/>
  <arg name="model" default="$(find urdf_tutorial)/urdf/08-macroed.urdf.xacro"/>

  <!-- 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="debug" value="$(arg debug)" />
    <arg name="gui" value="$(arg gui)" />
    <arg name="paused" value="$(arg paused)"/>
    <arg name="use_sim_time" value="$(arg use_sim_time)"/>
    <arg name="headless" value="$(arg headless)"/>
  </include>

  <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />

  <!-- push robot_description to factory and spawn robot in gazebo -->
  <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model"
        args="-z 1.0 -unpause -urdf -model robot -param robot_description" respawn="false" output="screen" />

  <node pkg="robot_state_publisher" type="robot_state_publisher"  name="robot_state_publisher">
    <param name="publish_frequency" type="double" value="30.0" />
  </node>

</launch>

篇二

把大象装进冰箱里第二步——给urdf打上gazebo的属性

这一步的目的其实很明显,就是为了让我们的机器人具备更多的属性,从而让我们的机器人在gazebo的仿真中能表现的更像在真实世界中一样!

我们知道,在现实世界中,一个物体光有质量和旋转惯量是完全不够的,这两个元素只是最基本的属性,表征这个物体可以被物理引擎观测到,但是仅仅如此是达不到我们想用gazebo的初衷的——通过这个平台模拟机器人在真实世界中的表现。举个简单的例子,一个物体除了质量外,另一个很重要的属性就是表面摩擦系数了,而这个属性link标签根本没有对其进行定义,那么这时候gazebo标签就派上了用场。

<!-- gazebo -->
<gazebo reference="car_link">
    <material>Gazebo/WoodFloor</material>
    <mu1>0.5</mu1>
    <mu2>0.5</mu2>
</gazebo>

tips:如果对于标签的值不确定的话,最好的方式就是敬而远之,不要填写,gazebo会给予一个默认可用的值的!擅自的修改会导致不好的结果。

这里我感觉很重要,比如之后可能会用到JointPositionController(.yaml文件里面),然后系统会让你定义pid的参数,如果你没有定义,系统会报错No p gain specified for pid.(这个错误可以忽略)但是你可以不用管它,原因如下:
Basically, if pid parameters were found, gazebo_ros_control will use pid controllers in ROS to control the joints (velocity or position) by effort. Otherwise, the joints will be controlled with gazebo methods.
所以,如果你对标签的值不确定的话,最好的方式就是别写

但是,如果你此时在rviz中打开模型的话,你会发现模型并没有这么漂亮(还是原来那个样子)
这也就是说,gazebo标签只是告诉gazebo怎么显示,并不会管ros中模型的形态以及属性,所以,这两个模块之间毫无疑问是有一个巨大的鸿沟隔着的!而能填补这个鸿沟的,就是整体框架图中的ros_control

对joint使用gazebo标签

这部分目前接触的不是很多

给joint添加真正的执行装置——transmission标签

一再强调,gazebo中的仿真都是基于物理引擎的,那么你想让一个模型运动,从本质上讲,必须要有力施加在模型上,就实际而言,我们必须在模型上加上执行器(通常情况下就是电机了),让模型运动起来。

transmission标签主要的针对对象是joint(因为一般两个link连接处的地方如果是非固定的,那么一定会存在一个执行装置来改变两个link的相对位置),transmission标签的作用就是给这个joint打上某种执行器的标签,有了执行器,gazebo就可以在物理层面上对模型进行驱动了。

个人理解就是添加了transmission标签后,gazebo中就有了模拟出来的执行器,当然后面会知道得有gazebo plugin才能使其生效。

这里对transmission标签内部的属性值稍作介绍:

  1. type: 这个标签不用担心了,只有一个值:transmission_interface/SimpleTransmission
  2. joint:首先要指明transmission服务的joint的名称,之后其中包含一个必填属性
  • hardwareInterface:该属性表明了这个joint是什么类型的,当前使用最多的(我的感觉是差不多只有这三种类型)是以下三个属性值:EffortJointInterface(通过输入功率控制电机),VelocityJointInterface(控制电机的转速),PositionJointInterface(控制电机的位置)。
  1. actuator:首先要为你的执行器起一个名字(一般就是什么什么motor),之后指定执行器的内部属性
  • mechanicalReduction:指明电机的减速比
  • hardwareInterface:这个可以不指明,因为在joint中已经指明了

transmission标签的interface和硬件无关

以上三个内部属性就是transmission的全部标签了,当然,有的朋友可能会问,作为执行器,必然是会有速度,功率的限制的,这个标签里面为什么没有这些参数?答:这些参数其实都有,只不过你要在上一节的joint标签中赋予相应的值,因为这些值说真的是属于joint的,并不属于transmission这个映射的属性

让执行器真正的能够进行硬件仿真——libgazebo_ros_control.so

负责将上层应用程序的信号量传输给gazebo进行仿真。例如,PID Loop计算得到了name=“wheel”的这个执行器需要输入10W的功率,那么经过JointCommand这个接口之后,信号就转化为了只有Effort Joint才能识别的信号,送给RobotHWSim,RobotHWSim接到这个信号之后,会找这个节点对应的transmission的是否也是Effort类型的,如果不是的话,gazebo就跪给你看了(当然并不是退出,而是你的这个信号就根本不会产生价值);如果是的话,信号的取值也很合理,那就可以开心的把它转化为gazebo能识别的信号给它了;一段时间后,gazebo将仿真的结果送回来,RobotHWSim拿着这个结果一算:Oh,这个关节运动了多少多少,就开开心心的吧这个结果送给JointState接口,由它转化为ros的信号。

在代码的任意位置添加如下代码:

 <!-- plagin -->
 <gazebo>
     <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
         <robotNamespace>/</robotNamespace>
         <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
     </plugin>
 </gazebo>

测试发现,没有gazebo plugin的时候ros发送消息在Gazebo不能进行实时的仿真。也就是说transmissoin标签没有生效。

[urdf_spawner-4] process has finished cleanly
log file: /home/jiaolu/.ros/log/95ebcd20-0c6b-11ea-8c32-58fb842d509b/urdf_spawner-4*.log

两天以来一直以为上面这个东东是个bug,其实不是。他只是模型重生之后自动将重生模型的进程kill啦
没发现前面几句面还有下面这一句信息:

Spawn status: SpawnModel: Successfully spawned entity

真是蠢啦

篇三

到目前为止,我们只是很执拗的在rviz和gazebo之间进行显示,但是由于两个模块是完全不一样的,内部的消息机制以及驱动机制都是差的比较多的,所以要想把两者嫁接起来,中间还必须有一个转换这的角色,这就是这个博客要讲的ros_control和plugin。

把大象装进冰箱里的第三步——连接gazebo和ros

我们在urdf文件中,对一些关节(joint)打上了给gazebo使用的transmission标签,我个人的理解是:transmission把TF(ros)的连接关系与仿真平台上的驱动设备(gazebo)联系在了一起,这样,当物理引擎下,这个驱动设备进行了动作的时候,ros就能知道是哪个TF需要变化;但是同理,我们要明白的一点是:transmission只是将两个标签联系在了一起,但是并不代表ros发送一个消息,gazebo中的该驱动设备就能收到!还是那句老话,ros中机器人形态的变化只需修改对应的TF就可以了,但是gezebo中必须要有物理层面的输入。

那么,为了将两者狠狠的联系起来,勤劳的程序员们就创造了一个中间者——ros_control和gazebo plugin

个人理解:inertial等物理参数的定义是将ROS和gazebo联系起来的第一步
那transmission可以认为是第二步,有了它,gazebo发布关节的消息ros就可以作出相应的TF的变化。但是ROS作出TF的变化gazebo却不一定能作出反应,因为TF的变化没有对应物理层面的输出。
为了将两者联系的更紧密,那就有了gazebo plugin和ros_control

gazebo plugin

Gazebo plugins give your URDF models greater functionality and can tie in ROS messages and service calls for (接收)sensor output and motor input
Gazebo plugins给予你的urdf模型更强大的功能,能和ROS的消息和服务联系起来,而这些消息和服务可以是传感器的输出和电机的输入(个人理解这里的传感器和电机的数据是gazebo发出的,因为传感器一般是输入数据而需要输出数据给电机,这里明显是数据的接收。也就是说gazebo法数据ros收数据)

gazebo_ros_control。其实这个plugin有些特殊,私认为这个plugin其实就是让所有transmission标签生效的一个插件,我们可以看看官方的原话:

In addition to the transmission tags, a Gazebo plugin needs to be added to your URDF that actually parses the transmission tags and loads the appropriate hardware interfaces and controller manager. By default the gazebo_ros_control plugin is very simple, though it is also extensible via an additional plugin architecture to allow power users to create their own custom robot hardware interfaces between ros_control and Gazebo.
Gazebo plugin一方面解析transmission,一方面也要加载适当的硬件借口和控制管理器

那么这里需要澄清的一点就是,这个plugin其实并没有将gazebo和ros连接起来(笔者这里所说的连接是指在ros中可以通过话题topic或者服务service来控制),其作用应该是提供了一个能控制gazebo中执行器运动的途径。

个人理解:以博文中控制小车运动的第一种方式来说,只是ros发布了一个速度值,就可以在gazebo中进行仿真啦,具体怎么仿真的我们并不清楚,我们也不能让小车停在我们想让它停止的位置。也就是说,到现在为止,我们只是能让gazebo中的机器人动起来啦,但是仅此而已。离我们的目标还差一点东西,应该就是ros_control了。

ros_control

回想一下,我们在程序中使用transmission标签把joint关节转换成了各式各样的在gazebo下的电机,随后通过对于整个机器人插入了一个叫做gazebo_ros_control的插件使的这些transmission生效,让这些电机与关节对应了起来,但是电机是gazebo中的啊,它即不能发送ros的消息,也不能订阅ros的消息,因此对于ros而言,这些电机是毫无用处的,因为不可读,也不可写;同理,对于gazebo,不管因为什么因素,我的电机转起来了之后,我只管仿真,没有必要每个周期再去计算一下TF变换了多少,整个机器人相对于原点移动了多少。

这里我的理解和博主一致,现在gazebo只是能用来仿真啦,比如我在ros中发布cmd_vel geometry_msgs/Twist消息,给出机器人的速度和角速度,那我gazebo只管仿真,按照你给定的速度走,但也仅止于此啦。那可能你想让你的机器人走个2m,然后停下来,怎么办。照现在来看是办不到的。

回到框架图中,除去上面的两个大方框,我们可以看到,当ros的消息传递过来的时候(绿色的方框),它并没有给gazebo,而是给了一个controller,经过controller中的控制器计算出来相应的值之后,数据流入了JointCommand接口(图下面有一个eg:EffortJointInterface的字样,说明该接口是有许多种的)中,然后由这个接口转交给gazebo模块;当gazebo计算数据完成之后,数据也是先流入一个叫做JointState的接口中,随后又流入了一个controller中,不过这个controller的目的就很明显了,就是计算整个机器人的TF,之后把TF发布出去。

上面提到的ros的消息(绿色的方框),官方的例子是关节轨迹(joint_trajectory),不得不说官方的例子很有针对性,非常能帮助我们理解。就以关节轨迹来说,我们输入关节轨迹到cotroller,它会帮我们解算出关节需要输出的力矩等等(当然具体输出什么应该和我们设置的controller有关的),然后通过硬件接口(比如EfforrtJointInterface)传递给gazebo。gazebo仿真完成之后同样经过一个硬件接口(比如JoinStateInterface)把当前的关节状态等送回到控制器(比如Joint_state_publisher),然后就可以把关节状态发布到ros,比如在rviz中完成机器人姿态的更新。

其中不得不说一下最耀眼的Controller Manager,这里先剧透一下说这些controller其实都是通过配置文件的形式载入到ros的参数服务器中(param service),之后通过ros的服务(service)来启动它们,如果每次都这么干的话,势必很浪费时间和精力,因此ros_control就创建一了Controller Manager的东西来帮助我们管理这些服务。

配置文件(比如joints.yaml)

主要就是把controller的配置参数给记录下来

具体的代码参见原博文

然后写个.launch 文件

具体的代码参见原博文

发送以下命令就可以让小车动起来了:

rostopic pub -r 30 /mobile_base_controller/cmd_vel geometry_msgs/Twist -- '[1.0,0,0]' '[0,0,0.0]'

注:用默认的gazebo插件,且命名空间要和.launch文件中controller的命名空间一致,否则报错如下:

“Controller Spawner couldn't find the expected controller_manager ROS interface.”

个人理解:加上ros_control后的控制方式和前面的直接用插件,然后发布话题控制的方式有什么区别?看起来好像挺像的。
目前的理解:以本例来看,好像确实没啥区别,都是发布话题直接控制速度。但是这是因为这个例子没有涉及到具体的我们想要达到的功能,比如我们要用轨迹规划,把你想要的轨迹输入控制器就好啦,自动帮你解算。但是只用插件就没法实现啦。暂时的理解,有待更新!

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

ROS与GAZEBO实时硬件仿真(4)——深入理解与总结 的相关文章

  • 蓝牙 UUID 解释

    一 xff0c 什么是 UUID UUID 可以简单理解为编号 xff0c 唯一的编号 xff0c 用于区分不同的个体 服务和特性都有各自的UUID 比如经典的9527 UUID 就跟身份证一样 xff0c 不管是你是局长还是科长 xff0
  • 【人工智能】传教士和野人问题(M-C问题)

    摘要 本题需要解决的是一般情况下的传教士和野人问题 xff08 M C问题 xff09 通过对问题的一般化 xff0c 我们用一个三元组定义了问题的状态空间 xff0c 并根据约束条件制定了一系列的操作规则 xff0c 最后通过两个启发式函
  • 【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?

    在算法竞赛中 xff0c 我们常常需要用到一个 无穷大 的值 xff0c 对于我来说 xff0c 大多数时间我会根据具体问题取一个99999999之类的数 xff08 显得很不专业啊 xff01 xff09 在网上看别人代码的时候 xff0
  • 【slighttpd】基于lighttpd架构的Server项目实战(7)—http-parser

    对于http服务器 xff0c http request的解析是比较麻烦的 xff0c 由于我们的重点并不在这上面 xff0c 所以这一部分不打算自己编写 xff0c 而是使用开源的http parser库 xff0c 下面我们将使用该库来
  • select和epoll 原理概述&优缺点比较

    这个问题在面试跟网络编程相关的岗位的时候基本都会被问到 xff0c 刚刚看到一个很好的比喻 xff1a 就像收本子的班长 xff0c 以前得一个个学生地去问有没有本子 xff0c 如果没有 xff0c 它还得等待一段时间而后又继续问 xff
  • 笔记-关于神经网络黑盒模型可解释性,可视化

    原博地址 xff1a 深度学习黑盒可视化指南 xff0c 从隐藏层开始 摘 xff1a 一旦神经网络接收到相当大的所需数据集后 xff0c 该网络就会使用其精确的知识 权重 来证明或识别未知数据样本上的模式 即在经过大量数据集训练以后 xf
  • C++11 多线程 future/promise简介

    1 lt future gt 头文件简介 Classes std future std future error std packaged task std promise std shared futureFunctions std as
  • C++异步调用利器future/promise实现原理

    前言 在异步编程中 xff0c 各种回调将让人眼花缭乱 xff0c 代码分散 xff0c 维护起来十分困难 boost和C 43 43 11 的 future promise 提供了一个很好的解决方案 xff0c 使得代码更加漂亮 易维护
  • 【Heydrones】飞手百科第一篇:一定要看的无人机原理总结

    飞手百科 知识是最好的保险 本文目录 1 xff0c 无人机的飞行原理 2 xff0c 无人机的几大系统 3 xff0c 无人机的外观介绍 4 xff0c 无人机的专业术语 xff08 一 xff09 无人机的飞行原理 旋翼和轮子一样 xf
  • 【Tars】腾讯微服务框架Tars介绍

    目录 1 介绍2 设计思路3 整体架构4 平台特性 1 介绍 Tars是 基于名字服务 使用Tars协议 的高性能 RPC 开发框架 xff0c 同时配套一体化的 服务治理平台 xff0c 帮助个人或者企业快速的以微服务的方式构建自己稳定可
  • C++11常用新特性快速一览

    最近工作中 xff0c 遇到一些问题 xff0c 使用C 43 43 11实现起来会更加方便 xff0c 而线上的生产环境还不支持C 43 43 11 xff0c 于是决定新年开工后 xff0c 在组内把C 43 43 11推广开来 xff
  • 语法糖:萃取lambda表达式

    背景 现在手头主负责的服务代码 xff0c 基本上都用C 43 43 11来开发了 xff0c 异步编程使用的是TAF的future promise future的then函数 xff0c 接受的是一个Callback对象 xff0c 该对
  • hashmap C++实现分析

    一 简介 Map 是 Key Value 对映射的抽象接口 xff0c 该映射不包括重复的键 xff0c 即一个键对应一个值 在HashMap中 xff0c 其会根据hash算法来计算key value的存储位置并进行快速存取 本文介绍的C
  • SpringMVC(04) -- SpringMVC获取请求参数

    SpringMVC学习笔记 源码地址 4 1 xff09 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参 xff0c 此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的
  • docker删除所有容器/镜像

    1 想要删除容器 xff0c 则要先停止所有容器 xff08 当然 xff0c 也可以加 f强制删除 xff0c 但是不推荐 xff09 xff1a docker stop docker ps a q 2 删除所有容器 docker rm
  • php中常见的几种设计模式

    1 单例模式 单例模式可以说是面向对象语言里最常用 也是最简单的一种模式 单例就是单个实例 xff0c 单个对象的意思 xff0c 就是说我们去实例化一个类的时候 xff0c 不管调用多少次 xff0c 都永远只有一个实例 不会有多个 xf
  • Ubuntu查看文件大小或文件夹大小

    一 查看文件大小 查看文件大小的命令 xff1a ls l filename 会在终端输出 xff1a rw r r 1 root root 2147483648 Mar 5 09 39 filetemp0606 其中数字214748364
  • Git 遇到了 The remote end hung up unexpectedly -- early EOF -- index-pack failed 问题

    Git 遇到了 The remote end hung up unexpectedly early EOF index pack failed 问题 今天想 clone 在 gitlab 的 repo xff0c 结果在 clone 的过程
  • 【Docker】在Docker容器中运行VScode

    原文链接 xff1a 容器中的远程开发 Prerequisites VScodeDocker Desktop Steps 打开Docker xff1a 在Windows下出现鲸鱼图标且图标静止则打开成功 xff1b 检查Docker xff
  • github 常用命令汇总 更新代码和子模块的代码

    针对PX4代码 xff0c 在github库中建立了Firmware的分支 xff0c ADRC branch xff0c 用于存放修改的代码 xff0c 其中涉及了子模块ecl的修改 代码下载 xff1a git clone https

随机推荐

  • C、C++多线程编程

    本文的笔记来自于b站视频的爱编程的大丙 xff0c 博客链接 xff1a https subingwen cn xff0c 有做了相应的补充 xff01 一 线程概述 进程对应的虚拟地址空间的各个分区如图 xff1a 每个进程的虚拟地址空间
  • 【x86架构】中断基础介绍

    说明 本文讲的是Intel的x86架构下的中断 参考的文档主要如下所示 xff1a 64 ia 32 architectures software developer manual pdf PCI Express体系结构导读 x86 x64
  • Java中的this有哪四种用法

    JAVA中的this是一个非常重要的模块 在编程中有非常重要的地位 擅长用this的人常常可以使程序更加简洁和方便 今天来了解一下this的用法 java中this关键字必须放在非静态方法里面 xff0c this关键字代表自身 xff0c
  • 线程不执行delegate,防止线程结束

    如果我们将NSURLConnection放在线程中 xff0c 是不是delegate方法总是不会触发 xff1f 原因就是由于线程结束了 解决方法就是让线程在数据返回之前不结束 1 可以在线程中加一个timer防止结束 xff0c 这方法
  • vscode 配置 git (配置、暂存、推送、拉取、免密)

    前些天发现了一个巨牛的人工智能学习网站 xff0c 通俗易懂 xff0c 风趣幽默 xff0c 忍不住分享一下给大家 点击跳转到教程 vscode 中对 git 进行了集成 xff0c 很多操作只需点击就能操作 xff0c 无需写一些 gi
  • 计算机视觉3 SIFT特征提取与全景图像拼接

    1 原理 检测并提取图像的特征和关键点匹配两个图像之间的描述符使用RANSAC算法使用我们匹配的特征向量估计单应矩阵拼接图像 步骤一和步骤二过程是运用SIFT局部描述算子检测图像中的关键点和特征 xff0c SIFT特征是基于物体上的一些局
  • 高超声速滑翔飞行器摆动式机动突防弹道设计(源代码)

    谢愈 xff0c 刘鲁华等 xff0c 高超声速滑翔飞行器摆动式机动突防弹道设计 xff0c 航空学报 xff0c 2011 算法有两个控制量 xff1a 攻角和倾侧角 xff0c 攻角只是起辅助作用 xff0c 主要还是倾侧角的设计 由于
  • 4轴开发之串级PID调试技巧

    欢迎查看我原始的出处 xff1a http lindue com 17868 html 调节串环 PID 大概过程 xff08 注意修正反向 xff09 1 估计大概的起飞油门 2 调整角速度内环参数 3 将角度外环加上 xff0c 调整外
  • 2013第四届蓝桥杯省赛C++C组【第四题:幻方填空】

    第四题 标题 xff1a 幻方填空 题目描述 xff1a 幻方是把一些数字填写在方阵中 xff0c 使得行 列 两条对角线的数字之和都相等 欧洲最著名的幻方是德国数学家 画家迪勒创作的版画 忧郁 中给出的一个4阶幻方 他把1 2 3 16
  • SLAM 02.整体框架

    上一篇文章是从人类角度来分析SLAM技术 xff0c 其实任何计算机技术的实现都是从人类思维出发去解决实际问题 本篇从技术实现角度讲解SLAM的实现框架 SLAM在自主导航中的位置 在整个移动机器人自主导航 xff08 包括自动驾驶 xff
  • SLAM 04.视觉里程计-1-相机模型

    相机模型是理解视觉里程计之前的基础 本文主要是对高翔博士的 SLAM十四讲 的总结 视觉里程计就是要根据相机拍摄的多幅图像估计出机器人当前的位置 xff0c 然后再重建地图 单目相机 相机模型里涉及到如下几个坐标 xff1a 空间坐标 物理
  • 第n次安装ros遇到的第n个问题

    自从入坑ros以来 xff0c 在导师公司的要求下 xff0c 我在无数的台式机 xff0c 工控机 xff0c 笔记本里刷linux系统 xff0c 搭ros环境 按照百度的安装教程 xff1a 换源 但是每次都能遇到不同稀奇古怪的问题
  • c/c++常用资源 c/c++书籍下载

    c c 43 43 常用资源 aix在线文档 xff1a http publib16 boulder ibm com cgi bin ds rslt 1 各种c c 43 43 编译器 http www clipx net norton p
  • 关于Android应用支持IPV6

    今天看了一些关于Android应用关于支持IPV6的问题 xff0c 简单记录 ipv从地址来说比v4多了 xff0c 长度更长 1 正常来说OKHttp xff0c XUtils等上层网络框架是支持ipv6的 但是如果你的应用中用到了so
  • 面试 | 推荐几个程序员刷题的网站!面试必备!!!

    经常有朋友问我 xff0c 有没有在线刷题的网站推荐 为什么要用线上刷题呢 xff1f 确实有一定好处 xff0c 线上的笔试题有自动更新 xff0c 可以记录你刷题的记录 xff0c 更好的来统计你的错误率和错误题型 最主要的是方便 xf
  • Docker镜像构建过程记录

    Docker镜像构建过程记录 为公司一个java工程 xff0c 构建一个docker镜像 xff0c 并将镜像存入私有库中 记录一下操作过程 1 打包 这是一个spring boot的maven工程 xff0c 打包命令就很简单了 spa
  • 直流可调稳压电源的Proteus仿真设计(附仿真+论文等资料)

    注意 xff1a 全套资源获取 xff0c 请见文末说明 设计要求 1 输出电压在1 25V 37V可调 xff1b 2 最大输出电流为1 5A xff1b 3 电压调整精度达0 1 xff1b 摘要 直流稳压电源由电源变换器 桥式整流滤波
  • GPT PMBR size mismatch 解决方法

    https blog csdn net agave7 article details 83177858 root 64 debian home liyezhen src sbk debian 32bit build product tool
  • react router路由传参三种方式

    react router路由传参三种方式 xff1a 通过通配符传参 query传参和state传参 1 通配符传参 Route定义方式 xff1a lt Route path 61 39 path name 39 component 61
  • ROS与GAZEBO实时硬件仿真(4)——深入理解与总结

    声明 xff1a 本博客是对博主无人的回忆所写的ROS与GAZEBO实时硬件仿真系列文章的自我理解与总结 xff0c 所写内容是基于该博主的三篇博文的 xff0c 如果有幸被人参考 xff0c 建议先看完该博主的三篇文章再来看这篇文章 三篇