ROS URDF机器人建模

ROS URDF机器人建模

创建URDF模型

(1)创建机器人描述功能包

catkin_create_pkg mrobot_description urdf xacro

(2)mrobot_description下创建urdf, launch文件夹,在urdf文件夹内放置机器人模型的

URDF或xacro文件。launch文件夹内放置相关启动文件。

URDF例子mrobot_chassis.urdf:

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

    <link name="base_link">
        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.005" radius="0.13"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
    </link>

    <joint name="base_left_motor_joint" type="fixed">
        <origin xyz="-0.055 0.075 0" rpy="0 0 0" />        
        <parent link="base_link"/>
        <child link="left_motor" />
    </joint>

    <link name="left_motor">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.02" length = "0.08"/>
            </geometry>
            <material name="gray">
                <color rgba="0.75 0.75 0.75 1"/>
            </material>
        </visual>
    </link>

    <joint name="left_wheel_joint" type="continuous">
        <origin xyz="0 0.0485 0" rpy="0 0 0"/>
        <parent link="left_motor"/>
        <child link="left_wheel_link"/>
        <axis xyz="0 1 0"/>
    </joint>

    <link name="left_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.033" length = "0.017"/>
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9"/>
            </material>
        </visual>
    </link>

    <joint name="base_right_motor_joint" type="fixed">
        <origin xyz="-0.055 -0.075 0" rpy="0 0 0" />        
        <parent link="base_link"/>
        <child link="right_motor" />
    </joint>

    <link name="right_motor">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.02" length = "0.08" />
            </geometry>
            <material name="gray">
                <color rgba="0.75 0.75 0.75 1"/>
            </material>
        </visual>
    </link>

    <joint name="right_wheel_joint" type="continuous">
        <origin xyz="0 -0.0485 0" rpy="0 0 0"/>
        <parent link="right_motor"/>
        <child link="right_wheel_link"/>
        <axis xyz="0 1 0"/>
    </joint>

    <link name="right_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.033" length = "0.017"/>
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9"/>
            </material>
        </visual>
    </link>

    <joint name="front_caster_joint" type="fixed">
        <origin xyz="0.1135 0 -0.0165" rpy="0 0 0"/>
        <parent link="base_link"/>
        <child link="front_caster_link"/>
    </joint>

    <link name="front_caster_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0"/>
            <geometry>
                <sphere radius="0.0165" />
            </geometry>
            <material name="black">
                <color rgba="0 0 0 0.95"/>
            </material>
        </visual>
    </link>

</robot>

(3)urdf提供一些命令行工具,用于检测模型文件。安装命令

sudo apt-get install liburdfdom-tools

使用check_urdf命令对mrobot_chassis.urdf文件进行检查, 终端会显示如下所示信息。

$ check_urdf mrobot_chassis.urdf
robot name is: mrobot_chassis
---------- Successfully Parsed XML ---------------
root Link: base_link has 3 child(ren)
    child(1):  left_motor
        child(1):  left_wheel_link
    child(2):  right_motor
        child(1):  right_wheel_link
    child(3):  front_caster_link

使用urdf_to_graphiz命令查看urdf模型整体结构,会生成如下一个pdf文件。

$ urdf_to_graphiz mrobot_chassis.urdf
Created file mrobot_chassis.gv
Created file mrobot_chassis.pdf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eofvUUhi-1605342281577)(/mnt/hgfs/ROSNote/docs/image/mrobot-chassis-urdf整体结构.png)]

在rviz中显示URDF模型

(1)在mrobot_description功能包的launch文件夹中创建用于显示mrobot_chassis模型的launch文件display_mrobot_chassis_urdf.launch,内容如下

<launch>
	<param name="robot_description" textfile="$(find mrobot_description)/urdf/mrobot_chassis.urdf" />

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>
	
	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
	
	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
	
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrobot_description)/config/mrobot_urdf.rviz" required="true" />
</launch>

执行启动命令,启动如下窗口,但是显示界面了出现Global Status:Error, Fixed Frame错误。

需要进行一些设置才能正常显示模型,把FixedFrame下拉选项中选择base_link, 点击左下角add按钮,增加一个RobotModel。

roslaunch mrobot_description display_mrobot_chassis_urdf.launch 

在这里插入图片描述

在这里插入图片描述

最后显示的模型如下图所示

在这里插入图片描述

改进URDF模型

添加物理和碰撞属性

在base_link中加入和标签,描述机器人的物理属性和碰撞属性。

<?xml version="1.0" ?>
<robot name="mrobot_chassis">
    <link name="base_link">
	<inertial>
	    <mass value="2" />
	    <origin xyz="0 0 0" />
	    <inertia ixx="0.01" ixy="0.0" ixz="0.0"
		      iyy="0.01" iyz="0.0" izz="0.5" />
	</inertial>

        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.005" radius="0.13"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
	<collision>
	    <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.005" radius="0.13"/>
            </geometry>
	</collision>
    </link>

使用xacro优化URDF

URDF文件不支持代码复用的特性。xacro是URDF的升级版,后缀名为xacro。具有以下几点突出优势

(1)精简模型代码。可以通过宏创建的方式定义常量或复用代码。

(2)提供可编程接口。支持一些可编程接口,如常量、变量、数学公式、条件语句等

在模型标签中需要加入xacro声明:

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

常量定义及调用

定义常量方便改动机器人模型的参数。

定义

<xacro:property name="M_PI" value="3.14159" />

调用

<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />

调用数学公式

在"${}"语句中,不仅可以调用常量,也可以使用一些常用的数学公式,如加,减,除,负号,括号等,例如:

<origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0" />

使用宏定义

xacro文件可以使用宏定义来声明重复使用的代码模块,而且可以包含输入参数,类似编程中的函数概念。

    <!-- 定义MRobot本体的宏 -->
    <xacro:macro name="mrobot_standoff_2in" params="parent number x_loc y_loc z_loc">
        <joint name="standoff_2in_${number}_joint" type="fixed">
            <origin xyz="${x_loc} ${y_loc} ${z_loc}" rpy="0 0 0" />
            <parent link="${parent}"/>
            <child link="standoff_2in_${number}_link" />
        </joint>

        <link name="standoff_2in_${number}_link">
            <inertial>
                <mass value="0.001" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.0001" ixy="0.0" ixz="0.0"
                         iyy="0.0001" iyz="0.0"
                         izz="0.0001" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
                <material name="black">
                    <color rgba="0.16 0.17 0.15 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
            </collision>
        </link>
    </xacro:macro>

如上定义了一个宏mrobot_standoff_2in,包含五个输入参数。调用该宏模块时,使用如下语句调用,设置输入参数即可:

<mrobot_standoff_2in parent="base_link" number="4" x_loc="${standoff_x/2}" y_loc="${standoff_y}" z_loc="${plate_height/2}"/>

xacro文件引用

改进后的机器人模型文件是mrobot.urdf.xacro, 详细内容如下

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

    <xacro:include filename="$(find mrobot_description)/urdf/mrobot_body.urdf.xacro" />

    <!-- MRobot机器人平台 -->
    <mrobot_body/>

</robot>

标签之间只有两行代码。

<xacro:include filename="$(find mrobot_description)/urdf/mrobot_body.urdf.xacro" />

第一行代码描述了该xacro文件所包含的其他xacro文件。声明关系后就可以调用被包含文件中的模块了。

 <mrobot_body/>

第二行代码就调用了被包含文件mrobot_body.urdf.xacro中的机器人模型的一个宏定义mrbot_body,该宏定义了整个机器人本体模型。

mrobot_body.urdf.xacro的内容如下

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

    <xacro:property name="M_PI" value="3.14159"/>
    <xacro:property name="wheel_radius" value="0.033"/>
    <xacro:property name="wheel_length" value="0.017"/>
    <xacro:property name="base_link_radius" value="0.13"/>
    <xacro:property name="base_link_length" value="0.005"/>
    <xacro:property name="motor_radius" value="0.02"/>
    <xacro:property name="motor_length" value="0.08"/>
    <xacro:property name="motor_x" value="-0.055"/>
    <xacro:property name="motor_y" value="0.075"/>
    <xacro:property name="plate_height" value="0.07"/>
    <xacro:property name="standoff_x" value="0.12"/>
    <xacro:property name="standoff_y" value="0.10"/>

    <!-- 定义MRobot本体的宏 -->
    <xacro:macro name="mrobot_standoff_2in" params="parent number x_loc y_loc z_loc">
        <joint name="standoff_2in_${number}_joint" type="fixed">
            <origin xyz="${x_loc} ${y_loc} ${z_loc}" rpy="0 0 0" />
            <parent link="${parent}"/>
            <child link="standoff_2in_${number}_link" />
        </joint>

        <link name="standoff_2in_${number}_link">
            <inertial>
                <mass value="0.001" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.0001" ixy="0.0" ixz="0.0"
                         iyy="0.0001" iyz="0.0"
                         izz="0.0001" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
                <material name="black">
                    <color rgba="0.16 0.17 0.15 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
            </collision>
        </link>
    </xacro:macro>

    <xacro:macro name="mrobot_body">
        <material name="Green">
            <color rgba="0.0 0.8 0.0 1.0"/>
        </material>
        <material name="yellow">
            <color rgba="1 0.4 0 1"/>
        </material>
        <material name="black">
            <color rgba="0 0 0 0.95"/>
        </material>
        <material name="gray">
            <color rgba="0.75 0.75 0.75 1"/>
        </material>

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

        <link name="base_link">
            <inertial>
                <mass value="2" />
                <origin xyz="0 0 0.0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0" izz="0.5" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
                <material name="yellow" />
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
            </collision>
        </link>

        <joint name="base_footprint_joint" type="fixed">
            <origin xyz="0 0 ${wheel_radius}" rpy="0 0 0" />        
            <parent link="base_footprint"/>
            <child link="base_link" />
        </joint>

        <link name="left_motor">
            <inertial>
                <origin xyz="0.0 0 0"/>
                <mass value="0.1" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}"/>
                </geometry>
                <material name="gray" />
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="base_left_motor_joint" type="fixed">
            <origin xyz="${motor_x} ${motor_y} 0" rpy="0 0 0" />        
            <parent link="base_link"/>
            <child link="left_motor" />
        </joint>


        <link name="left_wheel_link">
            <inertial>
                <origin xyz="0 0 0"/>
                <mass value="0.01" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
                <material name="white">
                    <color rgba="1 1 1 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="left_wheel_joint" type="continuous">
            <origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
            <parent link="left_motor"/>
            <child link="left_wheel_link"/>
            <axis xyz="0 1 0"/>
        </joint>

        <link name="right_motor">
            <inertial>
                <origin xyz="0.0 0 0"/>
                <mass value="0.1" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}" />
                </geometry>
                <material name="gray" />
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="base_right_motor_joint" type="fixed">
            <origin xyz="${motor_x} -${motor_y} 0" rpy="0 0 0" />        
            <parent link="base_link"/>
            <child link="right_motor" />
        </joint>

        <link name="right_wheel_link">
            <inertial>
                <origin xyz="0 0 0"/>
                <mass value="0.01" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
                <material name="white">
                    <color rgba="1 1 1 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="right_wheel_joint" type="continuous">
            <origin xyz="0 -${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
            <parent link="right_motor"/>
            <child link="right_wheel_link"/>
            <axis xyz="0 1 0"/>
        </joint>

        <link name="front_caster_link">
            <inertial>
                <origin xyz="0 0 0"/>
                <mass value="0.001" />
                <inertia ixx="0.0001" ixy="0.0" ixz="0.0"
                         iyy="0.0001" iyz="0.0" izz="0.0001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>
                <geometry>
                    <sphere radius="${wheel_radius/2}" />
                </geometry>
                <material name="black" />
            </visual>

            <collision>
                <origin xyz="0 0 0.01" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <sphere radius="${wheel_radius/2}" />
                </geometry>
            </collision>
        </link>

        <joint name="front_caster_joint" type="fixed">
            <origin xyz="${base_link_radius-wheel_radius/2} 0 -${wheel_radius/2}" rpy="0 0 0"/>
            <parent link="base_link"/>
            <child link="front_caster_link"/>
        </joint>

        <mrobot_standoff_2in parent="base_link" number="1" x_loc="-${standoff_x/2 + 0.03}" y_loc="-${standoff_y - 0.03}" z_loc="${plate_height/2}"/>
        <mrobot_standoff_2in parent="base_link" number="2" x_loc="-${standoff_x/2 + 0.03}" y_loc="${standoff_y - 0.03}" z_loc="${plate_height/2}"/>
        <mrobot_standoff_2in parent="base_link" number="3" x_loc="${standoff_x/2}" y_loc="-${standoff_y}" z_loc="${plate_height/2}"/>
        <mrobot_standoff_2in parent="base_link" number="4" x_loc="${standoff_x/2}" y_loc="${standoff_y}" z_loc="${plate_height/2}"/>

        <joint name="plate_1_joint" type="fixed">
            <origin xyz="0 0 ${plate_height}" rpy="0 0 0" />
            <parent link="base_link"/>
            <child link="plate_1_link" />
        </joint>

        <link name="plate_1_link">
            <inertial>
                <mass value="0.1" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0" izz="0.01" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
                <material name="yellow"/>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
            </collision>
        </link>


        <mrobot_standoff_2in parent="standoff_2in_1_link" number="5" x_loc="0" y_loc="0" z_loc="${plate_height}"/>
        <mrobot_standoff_2in parent="standoff_2in_2_link" number="6" x_loc="0" y_loc="0" z_loc="${plate_height}"/>
        <mrobot_standoff_2in parent="standoff_2in_3_link" number="7" x_loc="0" y_loc="0" z_loc="${plate_height}"/>
        <mrobot_standoff_2in parent="standoff_2in_4_link" number="8" x_loc="0" y_loc="0" z_loc="${plate_height}"/>

        <joint name="plate_2_joint" type="fixed">
            <origin xyz="0 0 ${plate_height}" rpy="0 0 0" />
            <parent link="plate_1_link"/>
            <child link="plate_2_link" />
        </joint>

        <link name="plate_2_link">
            <inertial>
                <mass value="0.01" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
                <material name="yellow" />
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
            </collision>
        </link>

    </xacro:macro>

</robot>

显示优化后的模型

xacro文件设计完成后,有两种方式在rviz中显示模型。

1.将xacro文件转换成URDF文件, 命令如下

rosrun xacro xacro.py mrobot.urdf.xacro >mrobot.urdf

这时候会生成一个新的URDF文件mrobot.urdf,使用上面launch文件可将URDF模型显示在rviz中。注意所使用了URDF文件名在launch文件中做相应修改。

launch文件内容如下

<launch>
	<param name="robot_description" textfile="$(find mrobot_description)/urdf/mrobot.urdf" />

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>
	
	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
	
	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
	
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrobot_description)/config/mrobot_urdf.rviz" required="true" />
</launch>
  1. 直接调用xacro文件解析器

    在launch文件中做如下配置,再运动启动文件即可。

<arg name="model" default="$(find xacro)/xacro --inorder '$(find mrobot_description)/urdf/mrobot.urdf.xacro'" />
<param name="robot_description" command="$(arg model)" />

launch文件的内容如下

<launch>
	<arg name="model" default="$(find xacro)/xacro --inorder '$(find mrobot_description)/urdf/mrobot.urdf.xacro'" />

	<param name="robot_description" command="$(arg model)" />

    <!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>

    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />

	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

    <!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrobot_description)/config/mrobot.rviz" required="true" />

</launch>

显示的模型如下图所示

在这里插入图片描述

到此,使用URDF建模的过程就走一遍了。

参考文献

[1]胡春旭. ROS机器人开发实践[M]. 机械工业出版社, 北京, 2018.5

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Galaxy_Robot

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值