ROS_Gazebo仿真

ROS  indigo 默认安装了Gazebo2可以用( locate 文件名 查看 )

/opt/ros/indigo/share/gazebo_ros/launch

1、在终端中启动Gazebo:

gazebo

如图为启动后的窗口界面:

 

2、Gazebo简单认识

使用ros命令打开的一个empty world 的gazebo 和我直接用gazebo命令打开的软件是没有区别的,因为都是空的内容里面。

但是实际使用是有区别的,使用roslaunch命令 打开的gazebo实际上是包含了一个ros通讯节点,这样就可以使用其他的ros指令将gazebo和你自己编写的文件联系起来。

着急学习的朋友建议直接上官网,里面有详细教程。

a)界面认识

 

这个空的世界中,只有一个大地模型和光源效果。

b)添加一些东西上去


如图,添加了两个球体和一个圆柱以及一个正方体。

 

c)基本工具介绍

移动工具

 

旋转工具


缩放工具

 

 


或者使用ctrl+B来进行地图编辑

 

3、接下来按照ROS的教程走

a)写一个urdf的模型文件

使用终端,建立并编辑urdf文件,我推荐gedit方便

gedit object.urdf


写入代码:

    <robot name="simple_box">
      <link name="my_box">
        <inertial>
          <origin xyz="2 0 0" />
          <mass value="1.0" />
          <inertia  ixx="1.0" ixy="0.0"  ixz="0.0"  iyy="100.0"  iyz="0.0"  izz="1.0" />
        </inertial>
        <visual>
          <origin xyz="2 0 1"/>
          <geometry>
            <box size="1 1 2" />
          </geometry>
        </visual>
        <collision>
          <origin xyz="2 0 1"/>
          <geometry>
            <box size="1 1 2" />
          </geometry>
        </collision>
      </link>
      <gazebo reference="my_box">
        <material>Gazebo/Blue</material>
      </gazebo>
    </robot>

保存关闭文本编辑器。

其中:

原文解释在这:

Here the origins of the inertial center, visual and collision geometry centers are offset in +x by 2m relative to the model origin. The box geometry primitive is used here for visual and collision geometry, and has sizes 1m wide, 1m deep and 2m tall. Note that visual and collision geometries do not always have to be the same, sometimes you want to use a simpler collision geometry to save collision detection time when running a dynamic simulation. The box inertia is defined as 1kg mass and principal moments of inertia ixx=izz=1 kg*m2 and iyy=100 kg*m2.

大意就是表达上面的urdf文件,构建了一个长1m宽1m高2m的盒子对应box size = 1 1 2,并且最后给予了惯性要求,对应ixx = 1 iyy = 100,其他的标签意思有空再去查一下,看翻译虽然有个大概理解,但是具体的区别大家自己尝试一下吧,但注意一下,gezebo reference = my_box 这个标签,对应的是导入gazebo中的模型名称。

接下来我们打开终端,使用命令行将这个文件导入到gazebo。


首先使用终端打开gazebo,这次使用roslaunch命令打开,因为要开一个节点:

<span style="font-size:14px;">roslaunch gazebo_ros empty_world.launch</span>


接下来使用rosrun命令将前面写的urdf文件放进去(记得先用终端cd到你放置urdf文件的路径下):

rosrun gazebo_ros spawn_model -file `pwd`/object.urdf -urdf -z 1 -model my_object  


运行结束之后,会发现你的gazebo多了一个蓝色的物体,如图:


一、使用ROS命令将新的对象加入到Gazebo模拟器中。

 

1)首先我们打开终端,roscore核心记得运行起来。

roscore


2)再开一个新的终端,使用roslaunch命令打开一个空的gazebo(注意这是重新开始了,如果你是直接从上篇看过来的,请直接进入到4)小节)

ros wiki上是用的是以下命令

roslaunch gazebo_worlds empty_world.launch

原因是因为官方在此处用的并不是ros indigo版本,可能是jade也可能是hydro,具体的我也不清楚,这里给大家推荐一个方法,如何确定gazebo_后面的参数,一般来说,ros会安装在/opt路径下,那么我们进入到/opt/ros/xxx(你的版本,我的是indigo)/share/ , 在这个文件夹下,可以找到你的gazebo_xxx,你可以看到你的后续应该跟的文件名称,是worlds 还是ros就在这里看。

如果你是indigo版本,使用以下命令

roslaunch gazebo_ros empty_world.launch

打开了一个新的Gazebo界面。

3)将上次写的蓝色盒子的urdf文件导入进去,如果你不明白这里的话,请看我上一篇博客。

rosrun gazebo_ros spawn_model -file `pwd`/object.urdf -urdf -z 1 -model my_object


4)使用roslaunch命令为模拟器中添加一张桌子
打开终端,输入以下命令

roslaunch gazebo_ros table.launch

有的朋友说,我没有找到gazebo_ros 的launch文件夹下有这个table.launch文件,当然没有,这个是要自己写的,官方知识让你看看,具体的要自己动手。

首先,使用终端,进入到gazebo_ros文件夹下。

cd /opt/ros/indigo/share/gazebo_ros


建立一个objects文件夹,这里主要用来储存后续的模型文件

sudo mkdir objects


然后,使用终端,进入到gazebo_ros下launch文件夹下。

cd /opt/ros/indigo/share/gazebo_ros/launch


你会发现这里有一些launch文件,比如你最开始是用的empty_worlds.launch文件就在这里。

接着,我们使用命令,创建一个table.launch文件

sudo gedit table.launch


将以下代码复制进去(这段代码是官方提供的,Indigo版本不适用,后面我会讲到如何改过来)

<launch>
  <!-- send table urdf to param server -->
  <param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_worlds)/objects/table.urdf.xacro" />

  <!-- push table_description to factory and spawn robot in gazebo -->
  <node name="spawn_table" pkg="gazebo" type="spawn_model" args="-urdf -param table_description -z 0.01 -model table_model" respawn="false" output="screen" />
</launch>


保存并关闭文件。
使用roslaunch命令运行我们的launch文件

rosluanch gazebo_ros table.launch


终端会提示错误,一大堆,使用indigo版本的人到这里其实是有三处错误,使用其他版本的也许只有一处,这里以indigo版本为例。
a)首先,你缺少了一个模型文件,即table的模型文件,我们使用的launch文件只是添加模型,但模型的具体文件不存在,需要我们手动建立。
我们进入到前面建立的objects文件夹下,建立一个名为table.urdf.xacro格式的文件

cd /opt/ros/indigo/share/gazebo_ros/objects

sudo gedit table.urdf.xacro

将以下代码填入这个文件中:

    <?xml version="1.0"?>
    <robot name="table"
           xmlns:xi="http://www.w3.org/2001/XInclude"
           xmlns:gazebo="http://playerstage.sourceforge.net/gazebo/xmlschema/#gz"
           xmlns:model="http://playerstage.sourceforge.net/gazebo/xmlschema/#model"
           xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
           xmlns:body="http://playerstage.sourceforge.net/gazebo/xmlschema/#body"
           xmlns:geom="http://playerstage.sourceforge.net/gazebo/xmlschema/#geom"
           xmlns:joint="http://playerstage.sourceforge.net/gazebo/xmlschema/#joint"
           xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
           xmlns:rendering="http://playerstage.sourceforge.net/gazebo/xmlschema/#rendering"
           xmlns:renderable="http://playerstage.sourceforge.net/gazebo/xmlschema/#renderable"
           xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
           xmlns:physics="http://playerstage.sourceforge.net/gazebo/xmlschema/#physics">
     
      <property name="table_height" value="0.55" />
      <property name="table_width" value="1.0" />
      <property name="table_depth" value="2.0" />
      <property name="leg_radius" value="0.02" />
      <property name="table_x" value="0.98" />
      <property name="table_y" value="0.0" />
      <property name="table_z" value="0.0" />
     
      <property name="table_top_thickness" value="0.05"/>
     
      <property name="M_PI" value="3.1415926535897931" />
     
     
      <!-- tabletop height is .55+.01+.025=.585 -->
      <link name="table_top_link">
        <inertial>
          <mass value="1.0" />
          <origin xyz="${table_x} ${table_y} ${table_z+table_height-table_top_thickness/2}" />
          <inertia ixx="1" ixy="0"  ixz="0"
                   iyy="1" iyz="0"
                   izz="1" />
        </inertial>
        <visual>
          <origin xyz="${table_x} ${table_y} ${table_z+table_height-table_top_thickness/2}" />
          <geometry>
            <box size="${table_width} ${table_depth} ${table_top_thickness}" />
          </geometry>
        </visual>
        <collision>
          <origin xyz="${table_x} ${table_y} ${table_z+table_height-table_top_thickness/2}" />
          <geometry>
            <box size="${table_width} ${table_depth} ${table_top_thickness}" />
          </geometry>
        </collision>
      </link>
      <gazebo reference="table_top_link">
        <material>Gazebo/Wood</material>
        <mu1>50.0</mu1>
        <mu2>50.0</mu2>
        <kp>1000000.0</kp>
        <kd>1.0</kd>
      </gazebo>
     
      <joint name="leg1_joint" type="fixed" >
        <parent link="table_top_link" />
        <origin xyz="${table_x+table_width/2} ${table_y+table_depth/2} ${table_z+table_height}" rpy="0 0 0" />
        <child link="leg1_link" />
      </joint>
      <link name="leg1_link">
        <inertial>
          <mass value="1.0" />
          <origin xyz="0 0 ${-table_height/2}" />
          <inertia ixx="0.1" ixy="0"  ixz="0"
                   iyy="0.1" iyz="0"
                   izz="0.01" />
        </inertial>
        <visual>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0 0 0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </visual>
        <collision>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0.0 0.0 0.0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </collision>
      </link>
      <gazebo reference="leg1_link">
        <material>Gazebo/Red</material>
        <mu1>1000.0</mu1>
        <mu2>1000.0</mu2>
        <kp>10000000.0</kp>
        <kd>1.0</kd>
        <selfCollide>true</selfCollide>
      </gazebo>
     
      <joint name="leg2_joint" type="fixed" >
        <parent link="table_top_link" />
        <origin xyz="${table_x-table_width/2} ${table_y+table_depth/2} ${table_z+table_height}" rpy="0 0 0" />
        <child link="leg2_link" />
      </joint>
      <link name="leg2_link">
        <inertial>
          <mass value="1.0" />
          <origin xyz="0 0 ${-table_height/2}" />
          <inertia ixx="0.1" ixy="0"  ixz="0"
                   iyy="0.1" iyz="0"
                   izz="0.01" />
        </inertial>
        <visual>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0 0 0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </visual>
        <collision>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0.0 0.0 0.0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </collision>
      </link>
      <gazebo reference="leg2_link">
        <material>Gazebo/Red</material>
        <mu1>1000.0</mu1>
        <mu2>1000.0</mu2>
        <kp>10000000.0</kp>
        <kd>1.0</kd>
        <selfCollide>true</selfCollide>
      </gazebo>
     
      <joint name="leg3_joint" type="fixed" >
        <parent link="table_top_link" />
        <origin xyz="${table_x+table_width/2} ${table_y-table_depth/2} ${table_z+table_height}" rpy="0 0 0" />
        <child link="leg3_link" />
      </joint>
      <link name="leg3_link">
        <inertial>
          <mass value="1.0" />
          <origin xyz="0 0 ${-table_height/2}" />
          <inertia ixx="0.1" ixy="0"  ixz="0"
                   iyy="0.1" iyz="0"
                   izz="0.01" />
        </inertial>
        <visual>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0 0 0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </visual>
        <collision>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0.0 0.0 0.0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </collision>
      </link>
      <gazebo reference="leg3_link">
        <material>Gazebo/Red</material>
        <mu1>1000.0</mu1>
        <mu2>1000.0</mu2>
        <kp>10000000.0</kp>
        <kd>1.0</kd>
        <selfCollide>true</selfCollide>
      </gazebo>
     
      <joint name="leg4_joint" type="fixed" >
        <parent link="table_top_link" />
        <origin xyz="${table_x-table_width/2} ${table_y-table_depth/2} ${table_z+table_height}" rpy="0 0 0" />
        <child link="leg4_link" />
      </joint>
      <link name="leg4_link">
        <inertial>
          <mass value="1.0" />
          <origin xyz="0 0 ${-table_height/2}" />
          <inertia ixx="0.1" ixy="0"  ixz="0"
                   iyy="0.1" iyz="0"
                   izz="0.01" />
        </inertial>
        <visual>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0 0 0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </visual>
        <collision>
          <origin xyz="0.0 0.0 ${-table_height/2}" rpy="0.0 0.0 0.0" />
          <geometry>
            <cylinder radius="${leg_radius}" length="${table_height}" />
          </geometry>
        </collision>
      </link>
      <gazebo reference="leg4_link">
        <material>Gazebo/Red</material>
        <mu1>1000.0</mu1>
        <mu2>1000.0</mu2>
        <kp>10000000.0</kp>
        <kd>1.0</kd>
        <selfCollide>true</selfCollide>
      </gazebo>
      <gazebo>
        <static>true</static>
        <canonicalBody>table_top_link</canonicalBody>
      </gazebo>
     
     
    </robot>

保存并关闭文件。

官方wiki一样ros版本的朋友你可以直接允许roslaunch table.launch命令了,然后跳过b)、c)两个小节,indigo版本的继续往下看
indigo版本运行roslaunch gazebo_ros table.launch文件你会发现出现这样的错误

那就对了,我们继续向下看。

b)修改table.launch文件
将table.launch的代码中的这句

<param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_worlds)/objects/table.urdf.xacro" />

替换为

<param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_ros)/objects/table.urdf.xacro" />

原因是因为我们使用的indigo版本对应的文件夹名称为gazebo_ros而非gazebo_worlds

保存退出,然后你发现运行roslaunch gazebo_ros table.launch
你会发现出现这样的错误:

 

关键错误出来了,ERROR:cannot launch node of type [gazebo/spawn_model]: gazebo
原来是在已经运行的节点名称不对,找不到这个gazebo名字啊
熟悉ros的朋友这会估计已经可以自己解决了,跳过c)也能自己正常做到了
好的,我们根据这个,找到我们前面打开的empty_worlds.launch这个文件
发现其中尾部有一句关键句为:

  <node name="gazebo" pkg="gazebo_ros" type="$(arg script_type)" respawn="false" output="screen"
    args="$(arg command_arg1) $(arg command_arg2) $(arg command_arg3) -e $(arg physics) $(arg extra_gazebo_args) $(arg world_name)" />

我们可以看到,pkg=“gazebo_ros”
而table.launch文件对应的为:

  <node name="spawn_table" pkg="gazebo" type="spawn_model" args="-urdf -param table_description -z 0.01 -model table_model" respawn="false" output="screen" />

发现不同,原来这里pkg="gazebo"

c)将pkg改正过来
我们再次编辑table.launch文件,将这段代码:

  <node name="spawn_table" pkg="gazebo" type="spawn_model" args="-urdf -param table_description -z 0.01 -model table_model" respawn="false" output="screen" />

替换为:

  <node name="spawn_table" pkg="gazebo_ros" type="spawn_model" args="-urdf -param table_description -z 0.01 -model table_model" respawn="false" output="screen" />

然后保存关闭。

那么ros indigo 版本下,正确的table.launch文件代码全文如下:

<launch>
  <!-- send table urdf to param server -->
  <param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_ros)/objects/table.urdf.xacro" />

  <!-- push table_description to factory and spawn robot in gazebo -->
  <node name="spawn_table" pkg="gazebo_ros" type="spawn_model" args="-urdf -param table_description -z 0.01 -model table_model" respawn="false" output="screen" />
</launch>


终端中运行正确的launch文件

roslaunch gazebo_ros table.launch


你会发现没有报错,如果这个时候还报错,你就从头看一下,是否是哪个步骤没做好?
然后你会看到你的gazebo模拟器中,出现了如图所示的一张桌子:

 

恭喜你,你已经学会了如何通过roslaunch命令导入相关的模型了。

5)使用launch文件导入多个模型
为了方便,我们把这两个物体写到一个launch文件中,一次性运行可以导入两个;
首先,把最开始写的object.urdf复制到/opt/ros/indigo/share/gazebo_ros/objects路径下,然后到launch文件夹下建立all.launch文件

sudo gedit all.launch


将以下代码复制:

<launch>
  <!-- send table urdf to param server -->
  <param name="table_description" command="$(find xacro)/xacro.py $(find gazebo_ros)/objects/table.urdf.xacro" />
  <param name="box_description" textfile="$(find gazebo_ros)/objects/object.urdf" />

  <!-- push table_description to factory and spawn robot in gazebo -->
  <node name="spawn_table" pkg="gazebo_ros" type="spawn_model" args="-urdf -param table_description -z 0.01 -model table_model" respawn="false" output="screen" />
  <node name="spawn_box" pkg="gazebo_ros" type="spawn_model" args="-urdf -param box_description -z 0.01 -model box_model" respawn="false" output="screen" />
</launch>

保存并关闭

运行all.launch文件

roslaunch gazebo_ros all.launch

你就会看到你的两个物体先后生成到模拟器中,但要注意,如果你的模拟器中已经存在了这两个物体,那么不会重新添加,因为节点信息已经存在了。

热门文章

暂无图片
编程学习 ·

exe4j详细使用教程(附下载安装链接)

一、exe4j介绍 ​ exe4j是一个帮助你集成Java应用程序到Windows操作环境的java可执行文件生成工具&#xff0c;无论这些应用是用于服务器&#xff0c;还是图形用户界面&#xff08;GUI&#xff09;或命令行的应用程序。如果你想在任务管理器中及Windows XP分组的用户友好任务栏…
暂无图片
编程学习 ·

AUTOSAR从入门到精通100讲(126)-浅谈车载充电系统通信方案

01 引言 本文深入研究车载充电系统策略,设计出一套基于电动汽车电池管理系统与车载充电机的CAN通信协议,可供电动汽车设计人员参考借鉴。 02 电动汽车充电系统通讯网络 电动汽车整车控制系统中采用的是CAN总线通信方式,由一个整车内部高速CAN网络、内部低速CAN网络和一个充电…
暂无图片
编程学习 ·

CMake(九):生成器表达式

当运行CMake时&#xff0c;开发人员倾向于认为它是一个简单的步骤&#xff0c;需要读取项目的CMakeLists.txt文件&#xff0c;并生成相关的特定于生成器的项目文件集(例如Visual Studio解决方案和项目文件&#xff0c;Xcode项目&#xff0c;Unix Makefiles或Ninja输入文件)。然…
暂无图片
编程学习 ·

47.第十章 网络协议和管理配置 -- 网络配置(八)

4.3.3 route 命令 路由表管理命令 路由表主要构成: Destination: 目标网络ID,表示可以到达的目标网络ID,0.0.0.0/0 表示所有未知网络,又称为默认路由,优先级最低Genmask:目标网络对应的netmaskIface: 到达对应网络,应该从当前主机哪个网卡发送出来Gateway: 到达非直连的网络,…
暂无图片
编程学习 ·

元宇宙技术基础

请看图&#xff1a; 1、通过AR、VR等交互技术提升游戏的沉浸感 回顾游戏的发展历程&#xff0c;沉浸感的提升一直是技术突破的主要方向。从《愤怒的小鸟》到CSGO,游戏建模方式从2D到3D的提升使游戏中的物体呈现立体感。玩家在游戏中可以只有切换视角&#xff0c;进而提升沉浸…
暂无图片
编程学习 ·

flink的伪分布式搭建

一 flink的伪分布式搭建 1.1 执行架构图 1.Flink程序需要提交给 Job Client2.Job Client将作业提交给 Job Manager3.Job Manager负责协调资源分配和作业执行。 资源分配完成后&#xff0c;任务将提交给相应的 Task Manage。4.Task Manager启动一个线程以开始执行。Task Manage…
暂无图片
编程学习 ·

十进制正整数与二进制字符串的转换(C++)

Function one&#xff1a; //十进制数字转成二进制字符串 string Binary(int x) {string s "";while(x){if(x % 2 0) s 0 s;else s 1 s;x / 2;}return s; } Function two&#xff1a; //二进制字符串变为十进制数字 int Decimal(string s) {int num 0, …
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统&#xff1a; 微信小程序——辩论管理前台涉及技术&#xff1a;WXML 和 WXS…
暂无图片
编程学习 ·

树莓派驱动DHT11温湿度传感器

1&#xff0c;直接使用python库 代码如下 import RPi.GPIO as GPIO import dht11 import time import datetimeGPIO.setwarnings(True) GPIO.setmode(GPIO.BCM)instance dht11.DHT11(pin14)try:while True:result instance.read()if result.is_valid():print(ok)print(&quo…
暂无图片
编程学习 ·

ELK简介

ELK简介 ELK是三个开源软件的缩写&#xff0c;Elasticsearch、Logstash、Kibana。它们都是开源软件。不过现在还新增了一个 Beats&#xff0c;它是一个轻量级的日志收集处理工具(Agent)&#xff0c;Beats 占用资源少&#xff0c;适合于在各个服务器上搜集日志后传输给 Logstas…
暂无图片
编程学习 ·

Linux 基础

通常大数据框架都部署在 Linux 服务器上&#xff0c;所以需要具备一定的 Linux 知识。Linux 书籍当中比较著名的是 《鸟哥私房菜》系列&#xff0c;这个系列很全面也很经典。但如果你希望能够快速地入门&#xff0c;这里推荐《Linux 就该这么学》&#xff0c;其网站上有免费的电…
暂无图片
编程学习 ·

Windows2022 无线网卡装不上驱动

想来 Windows2022 和 windows10/11 的驱动应该差不多通用的&#xff0c;但是死活装不上呢&#xff1f; 搜一下&#xff0c;有人提到 “默认安装时‘无线LAN服务’是关闭的&#xff0c;如果需要开启&#xff0c;只需要在“添加角色和功能”中&#xff0c;选择开启“无线LAN服务…
暂无图片
编程学习 ·

【嵌入式面试宝典】版本控制工具Git常用命令总结

目录 创建仓库 查看信息 版本回退 版本检出 远程库 Git 创建仓库 git initgit add <file> 可反复多次使用&#xff0c;添加多个文件git commit -m <message> 查看信息 git status 仓库当前的状态git diff 差异对比git log 历史记录&#xff0c;提交日志--pret…
暂无图片
编程学习 ·

用Postman生成测试报告

newman newman是一款基于nodejs开发的可以运行postman脚本的工具&#xff0c;使用Newman&#xff0c;可以直接从命令运行和测试postman集合。 安装nodejs 下载地址&#xff1a;https://nodejs.org/en/download/ 选择自己系统相对应的版本内容进行下载&#xff0c;然后傻瓜式安…
暂无图片
编程学习 ·

Java面向对象之多态、向上转型和向下转型

文章目录前言一、多态二、引用类型之间的转换Ⅰ.向上转型Ⅱ.向下转型总结前言 今天继续Java面向对象的学习&#xff0c;学习面向对象的第三大特征&#xff1a;多态&#xff0c;了解多态的意义&#xff0c;以及两种引用类型之间的转换&#xff1a;向上转型、向下转型。  希望能…