ROS 2边学边练(44)-- 从头开始构建一个视觉机器人模型

news2024/11/21 0:39:51

前言

        从此篇开始我们就开始接触URDF(Unified Robot Description Format,统一机器人描述格式),并利用其语法格式搭建我们自己的机器人模型。

动动手

        开始之前我们需要确认是否安装joint_state_publisher功能包,如果有安装过二进制版本的urdf_tutorial,也是可以的(教程里提到的所有机器人模型都可以在urdf_turial包里面找见,运行示例也是直接调用里面这些),否则需要更新下源并下载安装。

        如果没有安装,参考下面的命令。

安装依赖

$sudo apt install ros-iron-joint-state-publisher-gui ros-iron-joint-state-publisher
$sudo apt install ros-iron-xacro

安装urdf_tutorial 

$sudo apt update
$sudo apt install ros-iron-urdf-tutorial

 注意:还有其他方法可以下载urdf_tutorial功能包源工程,但均有问题。如git clone -b ros2 https://github.com/ros/urdf_tutorial.git,下载不了,再比如git clone https://github.com/ros/urdf_tutorial.git,可以下载,通过浏览器进入查看会发现最近的更新时间都是3年前了,且用的是catkin,最后colcon build --package-select urdf_tutorial会报错,构建不了。

如果大家用的是虚拟机,但是Ubuntu网络没有对应的ipv4,无法ping目标网络,那可能是虚拟机的网络配置问题,可以通过虚拟机->设置->网络适配器(桥接自动),选择桥接+复制物理网络连接状态。 

        关于urdf里面的机器人,一般由关节(joint,起连接作用)和连杆(link,多个link可由joint相衔接)构成,比如一个简单的机械臂,其组成如下。

单个形状

        我们先从单独一个几何形状开始逐步组装成R2D2机器人。[原文件:01-myfirst.urdf]

<?xml version="1.0"?>
<robot name="myfirst">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>
</robot>

        这段urdf代码定义了一个叫myfirst的机器人,它只包含一个连接base_link,其视觉外观是一个长为0.6米半径为0.2米的圆柱体(cylinder)。是不是一目了然,毫无压力。

        我们来试试启动一个launch文件,看看这个圆柱体实际的效果如何:

$ros2 launch urdf_tutorial display.launch.py model:=urdf/01-myfirst.urdf

上面的语句实际上做了三件事:

  • 加载特定的模型文件(01-myfirst.urdf)并且将此文件保存为robot_state_publisher节点的一个参数;
  • 运行节点,发布sensor_msgs/msg/JointState数据类型消息,并转换之;
  • 开启Rviz(读取配置文件中的参数加载)。

 最终效果如下:

注意点:

  • 固定坐标系是网格中心所在的变换坐标系。在这里,它是由我们的一个连接(或称为部分)base_link所定义的坐标系;
  • 视觉元素(即圆柱体)的默认原点位于其几何中心。因此,圆柱体的一半位于网格之下。

多个形状

        加大一点难度,我们在上述圆柱体的基础上再增加一个形状部件。在开头也提到了关节(joint),如果要在一个模块上添加另外一个模块,我们必须确定好joint,解析器才能知道第二个模块所放的位置,对于这个joint,大体上有两种,活动的(比如能旋转)和固定的,我们先来个固定的joint。[原文件:02-multipleshapes.urdf]

<?xml version="1.0"?>
<robot name="multipleshapes">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
  </joint>

</robot>

        机器人multipleshapes中,第一个link还是我们的圆柱体base_link,第二个link是需要组装到base_link上的right_leg(长方体box,长宽高0.6m*0.1m*0.2m),在最后我们看到有加了个joint,名字为base_to_right_leg,类型是固定(fixed),其父组件为base_link,子组件为right_leg,也即right_leg是通过base_to_right_leg这个joint连接组装到base_link上的。子组件的位置取决于父组件的位置。

$ros2 launch urdf_tutorial display.launch.py model:=urdf/02-multipleshapes.urdf

        base_link和right_leg重叠在一块了,这是由于它们共用了同样的原点(默认),如果不想它们重叠,那我们就需要定义多个原点。

原点

        我们来定义多个原点使得各个组件之间不再穿插。R2D2的腿部连接在其躯干的上半部分,位于侧面。所以我们指定关节的原点就在那里(躯干上半部)。同时,它(关节)并不是连接在腿部的中间,而是连接在腿部的上部,因此我们也必须调整腿部的原点位置。我们还需要旋转腿部,使其竖直站立。[原文件:03-origins.urdf]

<?xml version="1.0"?>
<robot name="origins">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>

</robot>

        我们先从joint属性看起,关节的原点是根据父参考坐标系来定义的。因此,我们在y方向上偏移了-0.22米(即向我们的左边,但相对于坐标轴是向右的),在z方向上偏移了0.25米(即向上)。这意味着无论子连接(child link)的视觉原点标签如何,子连接的原点都会向上并向右偏移。由于我们没有指定rpy(roll pitch yaw)属性,子坐标系将默认与父坐标系具有相同的方向。

        接着再看看right_leg,它的原点既有xyz偏移量也有rpy偏移量。由于我们希望腿部连接在顶部,我们将原点向下偏移,将z偏移量设置为-0.3米(right_leg的原点是相对于joint原点位置作变化,z值偏移-0.3,就能将长方体的顶部尽量接近圆柱体的顶部)。并且,由于我们希望腿部的长部分与z轴平行,我们围绕Y轴旋转视觉部分PI/2(即90度)。

$ros2 launch urdf_tutorial display.launch.py model:=urdf/03-origins.urdf

  • 启动文件(launch)在运行包时会基于我们的URDF为每个link生成TF帧,而Rviz会利用这些TF帧信息计算并显示出各个形状体的对应所在。
  • 如果给定的URDF link没有对应的TF帧,那么它将被放置在原点位置,并以白色显示(相关问题)。

物质属性

        原文标题为Material Girl,既幽默又如实,但我就翻译的严肃点了,莫怪。机器人上的link上面的效果都是红色,但是如果我们要自定义各个link的颜色(或其他属性)可不可以呢,当然了,我们可以在urdf文件里指定material标签即可。[原文件:04-materials.urdf]

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

  <material name="blue">
    <color rgba="0 0 0.8 1"/>
  </material>

  <material name="white">
    <color rgba="1 1 1 1"/>
  </material>

  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
      <material name="blue"/>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
      <material name="white"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>

  <link name="left_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
      <material name="white"/>
    </visual>
  </link>

  <joint name="base_to_left_leg" type="fixed">
    <parent link="base_link"/>
    <child link="left_leg"/>
    <origin xyz="0 0.22 0.25"/>
  </joint>

</robot>

        我们在material标签里定义了“blue”(rgba通道)和“white”两种颜色,在link标签里面进行了引用,这会改变该link原先的颜色属性。material标签也可以定义在link属性的内部(其它的link也可以引用),甚至我们还可以使用贴图来渲染我们的机器人。

$ros2 launch urdf_tutorial display.launch.py model:=urdf/04-materials.urdf

补全模型

        最后,我们给机器人加上脚、轮子和头(增加了球体和一些mesh文件,后续我们还会用到)。[原文件:05-visual.urdf]

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

  <material name="blue">
    <color rgba="0 0 0.8 1"/>
  </material>
  <material name="black">
    <color rgba="0 0 0 1"/>
  </material>
  <material name="white">
    <color rgba="1 1 1 1"/>
  </material>

  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
      <material name="blue"/>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
      <material name="white"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0 -0.22 0.25"/>
  </joint>

  <link name="right_base">
    <visual>
      <geometry>
        <box size="0.4 0.1 0.1"/>
      </geometry>
      <material name="white"/>
    </visual>
  </link>

  <joint name="right_base_joint" type="fixed">
    <parent link="right_leg"/>
    <child link="right_base"/>
    <origin xyz="0 0 -0.6"/>
  </joint>

  <link name="right_front_wheel">
    <visual>
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.1" radius="0.035"/>
      </geometry>
      <material name="black"/>
    </visual>
  </link>
  <joint name="right_front_wheel_joint" type="fixed">
    <parent link="right_base"/>
    <child link="right_front_wheel"/>
    <origin rpy="0 0 0" xyz="0.133333333333 0 -0.085"/>
  </joint>

  <link name="right_back_wheel">
    <visual>
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.1" radius="0.035"/>
      </geometry>
      <material name="black"/>
    </visual>
  </link>
  <joint name="right_back_wheel_joint" type="fixed">
    <parent link="right_base"/>
    <child link="right_back_wheel"/>
    <origin rpy="0 0 0" xyz="-0.133333333333 0 -0.085"/>
  </joint>

  <link name="left_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 1.57075 0" xyz="0 0 -0.3"/>
      <material name="white"/>
    </visual>
  </link>

  <joint name="base_to_left_leg" type="fixed">
    <parent link="base_link"/>
    <child link="left_leg"/>
    <origin xyz="0 0.22 0.25"/>
  </joint>

  <link name="left_base">
    <visual>
      <geometry>
        <box size="0.4 0.1 0.1"/>
      </geometry>
      <material name="white"/>
    </visual>
  </link>

  <joint name="left_base_joint" type="fixed">
    <parent link="left_leg"/>
    <child link="left_base"/>
    <origin xyz="0 0 -0.6"/>
  </joint>

  <link name="left_front_wheel">
    <visual>
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.1" radius="0.035"/>
      </geometry>
      <material name="black"/>
    </visual>
  </link>
  <joint name="left_front_wheel_joint" type="fixed">
    <parent link="left_base"/>
    <child link="left_front_wheel"/>
    <origin rpy="0 0 0" xyz="0.133333333333 0 -0.085"/>
  </joint>

  <link name="left_back_wheel">
    <visual>
      <origin rpy="1.57075 0 0" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.1" radius="0.035"/>
      </geometry>
      <material name="black"/>
    </visual>
  </link>
  <joint name="left_back_wheel_joint" type="fixed">
    <parent link="left_base"/>
    <child link="left_back_wheel"/>
    <origin rpy="0 0 0" xyz="-0.133333333333 0 -0.085"/>
  </joint>

  <joint name="gripper_extension" type="fixed">
    <parent link="base_link"/>
    <child link="gripper_pole"/>
    <origin rpy="0 0 0" xyz="0.19 0 0.2"/>
  </joint>

  <link name="gripper_pole">
    <visual>
      <geometry>
        <cylinder length="0.2" radius="0.01"/>
      </geometry>
      <origin rpy="0 1.57075 0 " xyz="0.1 0 0"/>
    </visual>
  </link>

  <joint name="left_gripper_joint" type="fixed">
    <origin rpy="0 0 0" xyz="0.2 0.01 0"/>
    <parent link="gripper_pole"/>
    <child link="left_gripper"/>
  </joint>

  <link name="left_gripper">
    <visual>
      <origin rpy="0.0 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://urdf_tutorial/meshes/l_finger.dae"/>
      </geometry>
    </visual>
  </link>

  <joint name="left_tip_joint" type="fixed">
    <parent link="left_gripper"/>
    <child link="left_tip"/>
  </joint>

  <link name="left_tip">
    <visual>
      <origin rpy="0.0 0 0" xyz="0.09137 0.00495 0"/>
      <geometry>
        <mesh filename="package://urdf_tutorial/meshes/l_finger_tip.dae"/>
      </geometry>
    </visual>
  </link>
  <joint name="right_gripper_joint" type="fixed">
    <origin rpy="0 0 0" xyz="0.2 -0.01 0"/>
    <parent link="gripper_pole"/>
    <child link="right_gripper"/>
  </joint>

  <link name="right_gripper">
    <visual>
      <origin rpy="-3.1415 0 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://urdf_tutorial/meshes/l_finger.dae"/>
      </geometry>
    </visual>
  </link>

  <joint name="right_tip_joint" type="fixed">
    <parent link="right_gripper"/>
    <child link="right_tip"/>
  </joint>

  <link name="right_tip">
    <visual>
      <origin rpy="-3.1415 0 0" xyz="0.09137 0.00495 0"/>
      <geometry>
        <mesh filename="package://urdf_tutorial/meshes/l_finger_tip.dae"/>
      </geometry>
    </visual>
  </link>

  <link name="head">
    <visual>
      <geometry>
        <sphere radius="0.2"/>
      </geometry>
      <material name="white"/>
    </visual>
  </link>
  <joint name="head_swivel" type="fixed">
    <parent link="base_link"/>
    <child link="head"/>
    <origin xyz="0 0 0.3"/>
  </joint>

  <link name="box">
    <visual>
      <geometry>
        <box size="0.08 0.08 0.08"/>
      </geometry>
      <material name="blue"/>
    </visual>
  </link>

  <joint name="tobox" type="fixed">
    <parent link="head"/>
    <child link="box"/>
    <origin xyz="0.1814 0 0.1414"/>
  </joint>
</robot>
$ros2 launch urdf_tutorial display.launch.py model:=urdf/05-visual.urdf

头部(球体)的添加如下:

<link name="head">
  <visual>
    <geometry>
      <sphere radius="0.2"/>
    </geometry>
    <material name="white"/>
  </visual>
</link>

        此教程中的mesh文件(组件模型)来自于PR2机器人,每个模型都有一个单独的mesh文件,我们可以通过指定模型对应的路径(package://NAME_OF_PACKAGE/path)来使用它们。

<link name="left_gripper">
  <visual>
    <origin rpy="0.0 0 0" xyz="0 0 0"/>
    <geometry>
      <mesh filename="package://urdf_tutorial/meshes/l_finger.dae"/>
    </geometry>
  </visual>
</link>
  • mesh(网格)可以以多种不同的格式导入。STL格式相当常见,但引擎还支持DAE格式,DAE格式可以包含其自身的颜色数据,这意味着你不需要指定颜色/材质。通常这些是在单独的文件中。这些网格还引用了位于网格文件夹中的.tif文件(注意:这里可能有一个小错误,.tif 文件通常不是用于3D网格的颜色或纹理数据。更常见的是使用如 .png.jpg.dds 等格式的图片文件作为纹理。可能是这里提到的 .tif 是个特例或者是一个错误。在3D建模和渲染中,.tif 文件不如其他格式常见,但在某些情况下可能被使用。)。
  • mesh(网格)也可以使用相对缩放参数或边界框大小来进行尺寸调整。
  • 我们也可以在完全不同的包中引用mesh(网格)。

        到此我们的R2D2机器人就组装好了,下一步,我们挑战一下,洒点灵魂,让它动起来。

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

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

相关文章

C++ stack、queue以及deque

1、stack和queue常用接口 严格来说栈和队列的实现是容器适配器 1、常用接口&#xff1a; 栈&#xff1a;top、push、pop、size、emptystack - C Reference (cplusplus.com) 队列&#xff1a;top、push、pop、swap、size、emptyqueue - C Reference (cplusplus.com) 2、deque&a…

Pycharm安装包numpy和matplotlib安装

环境 python 3.12 Pycharm 2023.1 安装包 创建图表的 numpy 库和 matplotlib 库 安装过程出现的问题 setuptools工具包没有安装 Python packaging tool setuptools not found文件 -> 设置 -> 项目:xxx -> python解释器界面显示不出已安装的软件包&#xff0c;系…

MQTT服务搭建及python使用示例

1、MQTT协议 1.1、MQTT介绍 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的、基于发布/订阅模式的通信协议&#xff0c;通常用于物联网设备之间的通讯。它具有低带宽、低功耗和开放性等特点&#xff0c;适合在网络带宽有限或者网络连接不稳定…

pyinstaller 不是内部或外部命令,也不是可运行的程序或批处理文件的解决办法(详细)

首先我们需要查看是否安装了pyinstaller &#xff0c;可以在命令窗口输入命令pip list检查是否安装成功&#xff0c; 这里我们可以看见已经安装成功了的&#xff0c;如果没有安装可以执行安装命令 pip install pyinstaller 进行安装即可。 下一步我们排查pyinstaller的安装路…

Python数据可视化------地图

基础地图使用 # 地图基本演示 # 导包 from pyecharts.charts import Map from pyecharts.options import TitleOpts, VisualMapOpts# 准备地图对象 cmap Map() # 准备数据&#xff08;列表&#xff09; data [("北京市", 99), ("上海市", 199), ("…

为什么你创业总是失败?2024普通人如何创业?2024创业赛道!2024创业新风口!2024创业方向!2024普通人的机会!

为什么你做项目老是不赚钱&#xff0c;是你不够努力吗&#xff1f;是你运气不好吗&#xff1f; 如果都不是&#xff01;那一定是你的思维逻辑出了问题&#xff01; 先想一想你以前做的项目&#xff0c;有没有哪个符合以下条件&#xff1a;对客户有价值、寻找客源成本在可接受…

BFS专题——FloodFill算法:200.岛屿数量

文章目录 题目描述算法原理代码实现CJava 题目描述 题目链接&#xff1a;200.岛屿数量 PS:注意题目中每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。也就是说斜角是不算了&#xff0c; 例如示例二&#xff0c;是三个岛屿。 算法原理 这道题目是 DFS&#xff0…

商务分析方法与工具(二):Python的趣味快捷-序列结构解决电影推荐

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

【C语言】内存函数的概念,使用及模拟实现

Tiny Spark get dazzling some day. 目录 1. memcpy-- 函数原型-- 函数使用-- 函数的模拟实现 2.memmove-- 函数原型-- 函数使用-- 函数的模拟实现 3. memset-- 函数原型-- 函数使用-- 函数的模拟实现 4. memcmp-- 函数原型-- 函数使用-- 函数的模拟实现 1. memcpy 使用需包含…

3dmax-vray6渲染器参数设置

适用于3dmax2018-2023版本 一、【公用】 小图输出大小:1500*1125&#xff0c;勾选大气、效果&#xff1b; 大图输出大小:3000*2250&#xff0c;勾选大气、效果、置换&#xff1b; 二、【vray】 小图抗锯齿类型:渐进式&#xff1b;最小细分:1&#xff0c;最大细分:100&#…

C++新特性

1 智能指针 1.1 为什么需要智能指针 智能指针主要解决以下问题&#xff1a; 内存泄漏&#xff1a;内存手动释放&#xff0c;使用智能指针可以自动释放共享所有权指针的传播和释放&#xff0c;比如多线程使用同一个对象时析构问题&#xff0c;比如&#xff1a; C里面的四个智…

解决springboot项目的网站静态页面显示不全问题

在通过springboot搭建项目时&#xff0c;为了能够访问静态的前端页面&#xff0c;我们考虑到访问的优先级问题&#xff0c;通常选择将资源放在recourses/static的目录下&#xff0c;如下&#xff1a; 这时可能会出现类似于下面这种图片无法加载、没有按照指定位置显示的情况&am…

R语言:r画韦恩图

> setwd("") > library(openxlsx) > library(ggvenn) > data <- read.xlsx("韦恩图种2.xlsx") data$P <- ifelse(data$P 0, "F", "T") data$N <- ifelse(data$N 0, "F", "T")> data &l…

流星烛台如何交易?Anzo Capital昂首资本3步盈利收场

各位投资者通过之前的文章可以准确的辨认出什么是流星烛台了&#xff0c;但是各位投资者一旦遇到流星图案知道怎么交易吗?其实一点都不困难&#xff0c;只要掌握住流星图案的交易真棒&#xff0c;Anzo Capital昂首资本3步就可以盈利收场。 首先&#xff0c;投资者需要确定图…

技术速递|介绍 .NET MAUI 社区工具包 v8 :包含 TouchBehavior 支持!

作者&#xff1a;Gerald Versluis 排版&#xff1a;Alan Wang .NET MAUI 社区工具包团队很自豪地向您介绍 .NET MAUI 社区工具包的第 8 版&#xff01; 在这个最新的主要版本中&#xff0c;我们为您带来了备受期待的 TouchBehavior&#xff08;以前称为 TouchEffect&#xff0…

【C++】详解STL容器之一的 vector

目录 概述 迭代器 数据结构 优点和缺点 接口介绍 begin end rbegin rend resize reseve insert erase 其他一些接口 模拟实现 框架 获取迭代器 深浅拷贝 赋值重载 reseve resize 拷贝构造 构造 析构 insert erase 其他 概述 vector是STL的容器之一。…

二叉树遍历总结

7.二叉树 二叉树理论基础 二叉树的种类 在我们解题过程中二叉树有两种主要的形式&#xff1a;满二叉树和完全二叉树。 满二叉树 完全二叉树 二叉搜索树 平衡二叉搜索树 C中map、set、multimap&#xff0c;multiset的底层实现都是平衡二叉搜索树&#xff0c;所以map、set的增…

2024.5.8 2.二叉树的最大深度 (简单)

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输…

GZIP文件格式解析和Inflate静态Huffman解压缩

GZIP是封装了Deflate压缩的格式文件&#xff1b;Deflate使用了无压缩、HuffmanLZ77进行压缩&#xff1b;解压是Inflate&#xff0c;Huffman包括静态Huffman压缩和动态Huffman压缩两种模式。 Java语言实现了GZIP格式解析、Inflate的静态Huffman解压缩、CRC32校验 算法。 gzip文…

7-AMCA Mal,可通过与蛋白质上的巯基反应生成具有荧光的标记物

【产品概述】 7-AMCA Mal&#xff0c;也被称为7-AMCA maleimide&#xff0c;是一种在生物医学领域中常用的荧光染料。 中文名称&#xff1a;7-AMCA 马来酰亚胺 英文名称&#xff1a;7-AMCA Mal&#xff0c;7-AMCA maleimide CAS号&#xff1a;N/A 分子式&#xff1a;C18H17N3…