XTDrone-无人机与无人船协同初步-配置教程

news2025/1/21 1:03:22
说明:配置该教程时所使用的是Ubuntu20.04

1 海洋与无人船仿真环境搭建

cp -r ~/XTDrone/sitl_config/usv/* ~/catkin_ws/src/
cd catkin_ws
catkin build # or catkin_make

说明:由于官方所编写的脚本时几年之前的,所以很多东西不符合现在运行环境,因此编译时会出现很多报错,这是正常的,只需要按照提示进行修改就行。下面将是详细的报错解决办法,此外,为了节省解决报错的时间,我已将所有与关于本次配置相关的修改过的CmakeList.txt文件完整版均放在文章末尾,只需按照你的路径进行相应的修改即可使用,记得每次修改后要先保存再进行编译。

警告1

文件目录:/home/你的主机名/catkin_ws/src/wave_gazebo_plugins

这个警告指的是CMake策略CMP0054的旧行为即将被移除。CMake策略用于控制构建过程中的某些特定行为,当一个策略被标记为旧(OLD)时,意味着它在未来的CMake版本中可能会被移除,应该尽量使用新的(NEW)行为。

解决方案

为了消除这个警告,可以更新CMakeLists.txt文件中对应的策略设置。你可以查找并更新或添加以下行以使用新的行为:
cmake_policy(SET CMP0054 NEW)

具体步骤如下:
  1. 打开CMakeLists.txt文件。
  2. 找到第25行(或者附近)使用了cmake_policy指令的地方。
  3. 确保这一行是:
cmake_policy(SET CMP0054 NEW)

或者,如果没有这行指令,可以添加:
cmake_policy(SET CMP0054 NEW)

为什么会有这个警告?
CMake策略CMP0054涉及到如何处理if命令中的不明确表达式。在设置为旧行为(OLD)时,CMake会把字符串"0"、"FALSE"等视为布尔假值。在新行为(NEW)中,只有明确的布尔假值(例如OFFNO等)会被视为假。

警告2 (usv_gazebo_plugins的也同理)

文件目录:/home/你的主机名/catkin_ws/src/usv_gazebo_plugins

 警告3

修改后的内容:用以解决警告(修改后记得保存
std::string ShapeVolume::Display()
{
  switch (type)
  {
    case ShapeType::None:
      return "None";
    case ShapeType::Box:
      return "Box";
    case ShapeType::Cylinder:
      return "Cylinder";
    case ShapeType::Sphere:
      return "Sphere";
    default:
      return "Unknown"; // 或者一个适当的默认值
  }
}

警告4

OLD->NEW即可
文件目录/home/你的主机名/catkin_ws/src/wamv_gazebo

警告5 

同理,但是有两个地方,文件路径/home/ray/catkin_ws/src/vrx_gazebo

报错1

这意味着编译过程中尝试运行 python,但系统找不到这个命令。这通常是因为系统中没有安装 Python,或者 Python 安装在一个不同的路径下,或者系统中默认的 Python 解释器名称是 python3 而不是 python

解决方案

以下是几种可能的解决方法:

  1. 创建符号链接: 如果系统中安装了 Python 3,但没有 python 命令,可以创建一个符号链接,将 python 指向 python3

    sudo ln -s /usr/bin/python3 /usr/bin/python
    
    
  2. 修改脚本使用 python3: 如果可能的话,找到调用 Python 的地方,将 python 改为 python3。例如,在 CMakeLists.txt 或相关脚本中:

    /usr/bin/env python3
    
    
  3. 安装 Python: 如果系统中没有安装 Python,可以安装 Python。对于 Ubuntu 或其他基于 Debian 的系统,可以使用以下命令:

    sudo apt update
    sudo apt install python2
    
    

    如果需要安装 Python 3:

    sudo apt update
    sudo apt install python3
    
    

查找和修改脚本

a.查找项目中使用 python 的地方

grep -r "/usr/bin/env python" /home/ray/catkin_ws/src/vrx_gazebo

这将显示所有包含 "/usr/bin/env python" 的文件路径。

b.编辑这些文件

使用文本编辑器打开这些文件,并将 python 改为 python3。例如:
#!/usr/bin/env python3

完成上述步骤后,重新运行编译命令:
cd catkin_ws
catkin build

再次编译之后,又会出现新的警告和报错

警告1

这个警告是关于 CMake 的策略 CMP0048 的,它指出在 CMakeLists.txt 文件中的 project() 命令没有显式设置项目的版本信息,导致一些相关的 CMake 变量可能会被设置为空。这种警告通常不会导致编译失败,但建议根据最新的 CMake 策略设置来更新项目文件,以避免潜在的问题。

解决方案

由于其版本较老,不适合现在的应用,所以,最好对整个CMakeLists.txt 文件进行修改,修改后的文件如下:(可复制粘贴)
cmake_minimum_required(VERSION 3.0)
project(wave_gazebo_plugins VERSION 1.0.0)

###############################################################################
# Compile as C++11, supported in ROS Noetic and newer

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Set policy for CMake 3.1+. Use OLD policy to let FindBoost.cmake, dependency
# of gazebo, use quoted variables in if()
if(POLICY CMP0048)
  cmake_policy(SET CMP0048 NEW)
endif()

###############################################################################
# Other dependencies...

find_package(catkin REQUIRED COMPONENTS gazebo_ros)
find_package(gazebo REQUIRED)
find_package(Eigen3 REQUIRED)

############################################################################### 
# Catkin...

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES
    Hydrodynamics
    WavefieldModelPlugin
    WavefieldVisualPlugin
    wavegauge_plugin
  DEPENDS
    gazebo_ros
)

############################################################################### 
# Libraries...

# Hydrodynamics
add_library(Hydrodynamics
  SHARED
    src/Gazebo.cc
    src/Geometry.cc
    src/PhysicalConstants.cc
    src/Physics.cc
    src/Utilities.cc
    src/Wavefield.cc
    src/WavefieldEntity.cc
)

target_include_directories(Hydrodynamics
  PRIVATE
    ${PROJECT_SOURCE_DIR}/include
    ${Boost_INCLUDE_DIRS}
    ${catkin_INCLUDE_DIRS}
    ${EIGEN3_INCLUDE_DIR}
    ${GAZEBO_INCLUDE_DIRS}
    ${GAZEBO_MSG_INCLUDE_DIRS}
    ${IGNITION-COMMON_INCLUDE_DIRS}
    ${IGNITION-MATHS_INCLUDE_DIRS}
    ${IGNITION-MSGS_INCLUDE_DIRS}
)

target_link_directories(Hydrodynamics
  PRIVATE
    ${GAZEBO_LIBRARY_DIRS}
    ${IGNITION-COMMON_LIBRARY_DIRS}
    ${IGNITION-MATHS_LIBRARY_DIRS}
    ${IGNITION-MSGS_LIBRARY_DIRS}
)

target_link_libraries(Hydrodynamics
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
)

target_compile_features(Hydrodynamics PRIVATE cxx_std_14)
target_compile_options(Hydrodynamics PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_LIBRARIES_LIST Hydrodynamics)

############################################################################### 
# Plugins...

# WavefieldModelPlugin
add_library(WavefieldModelPlugin
  SHARED
    src/WavefieldModelPlugin.cc
)

target_link_libraries(WavefieldModelPlugin
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${WAVE_GAZEBO_LIBRARIES_LIST}
)

target_compile_features(WavefieldModelPlugin PRIVATE cxx_std_14)
target_compile_options(WavefieldModelPlugin PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_PLUGINS_LIST WavefieldModelPlugin)

# WavefieldVisualPlugin
add_library(WavefieldVisualPlugin
  SHARED
    src/WavefieldVisualPlugin.cc
)

target_link_libraries(WavefieldVisualPlugin
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${WAVE_GAZEBO_LIBRARIES_LIST}
)

target_compile_features(WavefieldVisualPlugin PRIVATE cxx_std_14)
target_compile_options(WavefieldVisualPlugin PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_PLUGINS_LIST WavefieldVisualPlugin)

# WavegaugePlugin
add_library(wavegauge_plugin
  SHARED
    src/wavegauge_plugin.cc
)

target_link_libraries(wavegauge_plugin
  WavefieldModelPlugin
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${WAVE_GAZEBO_LIBRARIES_LIST}
)

add_dependencies(wavegauge_plugin WavefieldModelPlugin)

target_compile_features(wavegauge_plugin PRIVATE cxx_std_14)
target_compile_options(wavegauge_plugin PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_PLUGINS_LIST wavegauge_plugin)

############################################################################### 
# Executables...


############################################################################### 
# Tests...

if(CATKIN_ENABLE_TESTING)

  catkin_add_gtest(UNIT_Wavefield_TEST src/Wavefield_TEST.cc)
  target_link_libraries(UNIT_Wavefield_TEST ${WAVE_GAZEBO_LIBRARIES_LIST})
  target_compile_features(UNIT_Wavefield_TEST PRIVATE cxx_std_14)
  target_compile_options(UNIT_Wavefield_TEST PRIVATE "-Wno-unknown-pragmas")

endif()

############################################################################### 
# Install

install(
  TARGETS
    ${WAVE_GAZEBO_LIBRARIES_LIST}
    ${WAVE_GAZEBO_PLUGINS_LIST}
    wavegauge_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(
  DIRECTORY include/${PROJECT_NAME}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.hh"
)

install(
  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.pb.*"
)

 警告2 同理进行修改即可

修改后的完整文件:
cmake_minimum_required(VERSION 3.0)
project(usv_gazebo_plugins VERSION 1.0.0)

# Set policy for CMake 3.1+. Use OLD policy to let FindBoost.cmake, dependency
# of gazebo, use quoted variables in if()
if(POLICY CMP0048)
  cmake_policy(SET CMP0048 NEW)
endif()

find_package(catkin REQUIRED COMPONENTS gazebo_dev roscpp message_generation xacro wave_gazebo_plugins usv_msgs)
find_package(Eigen3 REQUIRED)

###################################
## catkin specific configuration ##
###################################

catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS message_runtime gazebo_dev roscpp wave_gazebo_plugins
)

# Plugins require c++14

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include_directories( include
  ${catkin_INCLUDE_DIRS}
  ${EIGEN3_INCLUDE_DIRS}
)
link_directories(
  ${catkin_LIBRARY_DIRS}
)

## Declare a C++ library
add_library(buoyancy_gazebo_plugin
  src/buoyancy_gazebo_plugin.cc
  src/shape_volume.cc
  src/polyhedron_volume.cc
)
target_link_libraries(buoyancy_gazebo_plugin
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS buoyancy_gazebo_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_dynamics_plugin
  src/usv_gazebo_dynamics_plugin.cc
)
target_link_libraries(usv_gazebo_dynamics_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_dynamics_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_thrust_plugin
  src/usv_gazebo_thrust_plugin.cc
)
target_link_libraries(usv_gazebo_thrust_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_thrust_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_wind_plugin
  src/usv_gazebo_wind_plugin.cc
)
target_link_libraries(usv_gazebo_wind_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_wind_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_acoustic_pinger_plugin
  src/acoustic_pinger_plugin.cc
)
add_dependencies(usv_gazebo_acoustic_pinger_plugin usv_msgs_generate_messages_cpp)
target_link_libraries(usv_gazebo_acoustic_pinger_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_acoustic_pinger_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

set(XACRO_INORDER)
if(DEFINED ENV{ROS_DISTRO})
  if($ENV{ROS_DISTRO} STREQUAL "kinetic")
    set(XACRO_INORDER INORDER)
  endif()
endif()

# Generate demo world files from xacro and install
xacro_add_files(
  worlds/buoyancy_plugin_demo.world.xacro
  ${XACRO_INORDER} INSTALL DESTINATION worlds
)
install(DIRECTORY worlds/
        DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/worlds)

if(CATKIN_ENABLE_TESTING)
  # buoyancy plugin test
  catkin_add_gtest(buoyancy_plugin_test test/buoyancy_test.cc)
  target_link_libraries(buoyancy_plugin_test buoyancy_gazebo_plugin)
endif()
 修改完成后,再次编译会先后出现如下的几个报错:

上述这个报错是找不到是因为在编译wave_gazebo_plugins功能包时,出现了无法找到 gazebo/gazebo.hhgazebo/common/Assert.hh 头文件问题。

解决办法:

a.输入如下命令来查询 Gazebo 的安装路径。
pkg-config --cflags gazebo
pkg-config --libs gazebo
输入后会有以下输出:它包含安装路径,版本等
  • --cflags 选项会显示编译时所需的头文件路径。
  • --libs 选项会显示链接时所需的库路径。

 或者输入如下指令直接寻找报错的未寻找到的文件:
find /usr -name gazebo.hh  # 文件名根据你的报错来修改
该命令运行后的正常输入示例如下(安装了gazebo的前提下)

 b. 查询结束后,按照你的查询结果修改如下两条代码,并将其加入到wave_gazebo_plugins功能包的CMakeLists.txt文件中,并保存,确保将 GAZEBO_INCLUDE_DIRS 和 GAZEBO_LIBRARY_DIRS 变量中的路径更新为你实际系统中的路径。
# 根据你所查询到的路径和版本来进行修改
set(GAZEBO_INCLUDE_DIRS "/usr/include/gazebo-9" "/usr/include/sdformat-6.3" "/usr/include/ignition/transport4" "/usr/include/ignition/msgs1" "/usr/include/ignition/math4")
set(GAZEBO_LIBRARY_DIRS "/usr/lib/x86_64-linux-gnu/gazebo-9/plugins")
具体添位置见下图

c.增加如下代码,以确保包含 Gazebo 的头文件路径和有链接 Gazebo 的库文件路径
# 该条代码添加到target_include_directories(Hydrodynamics PRIVATE)中
${GAZEBO_INCLUDE_DIRS} # 确保包含 Gazebo 的 include 路径
target_link_directories(Hydrodynamics
PRIVATE
${GAZEBO_LIBRARY_DIRS} # 确保链接 Gazebo 的库路径
)
具体添加位置见下图

至此,关于编译 wave_gazebo_plugins功能包时,gazebo头文件无法找到的相关报错即可解决。

报错2 以下三个报错均是与找不到与OGRE库相关的头文件有关,因为Gazebo 依赖于 OGRE 进行渲染,所以你需要安装 OGRE 库及其开发文件。

解决方法:

a.输入以下命令确保你的系统已经安装了必要的 OGRE 包
sudo apt-get install libogre-1.9-dev
b. 如果你已经安装了 OGRE,但还是出现找不到头文件的问题,你需要手动指定 OGRE 的包含路径和库路径。在 CMake 文件中,可以添加如下内容:
首先输入如下命令,检查你的OGRE路径
find /usr -name OGRE

然后在 CMake 文件中,分别添加如下内容:
# 添加额外的 OGRE 包含路径,确保找到所需的头文件 根据你上面所查找的路径来改
list(APPEND OGRE_INCLUDE_DIRS "/usr/include/OGRE")
list(APPEND OGRE_INCLUDE_DIRS "/usr/include/OGRE/Paging")
具体添加位置如下图所示

${OGRE_INCLUDE_DIRS}     # 确保包含 OGRE 的额外路径
具体添加位置如下图所示

${OGRE_INCLUDE_DIRS}  # 确保包含 OGRE 的 include 路径
具体添加位置如下图所示

  ${OGRE_LIBRARIES}  # 确保链接 OGRE 库
具体添加位置如下图所示

至此,关于编译 wave_gazebo_plugins功能包时与 OGRE相关的头文件找不到的报错即可解决。由于官方所给的文件版本较老,不适应当前的运行环境,所以我将所有与关于本次配置相关的修改过的CmakeList.txt文件完整版均放在文章末尾,只需按照你的路径进行相应的修改即可使用,记得每次修改后要先保存再进行编译。

保存后,在运行以下代码进行编译

cd catkin_ws/
catkin build

编译成功后就会如下图所示

2 启动仿真

运行如下代码
roslaunch px4 sandisland.launch
运行后会出现如下报错:

解决办法

原因是PX4_Firmware/launch文件夹中并没有sandisland.launch文件,只需将
/home/你的主机名/catkin_ws/src/vrx_gazebo/launch目录下的sandisland.launch文件复制放在PX4_Firmware/launch中即可

成功运行sandisland.launch文件的效果如下图所示,但是你会发现在仿真环境中并没有无人机,与官网上的视频不同。

解决办法

利用多无人机生成脚本生成多无人机启动launch文件,详细教程见:XTDrone-多机仿真-配置教程-CSDN博客
然后将启动文件中生生成多无人机部分代码加入到PX4_Firmware/launch下的sandisland.launch文件中,并修改相应的位置参数,修改后的完整sandisland.launch文件如下:(可直接复制粘贴,修改后记得保存)
<?xml version="1.0"?>
<launch>
  <env name="ROSCONSOLE_CONFIG_FILE" value="$(find vrx_gazebo)/config/custom_rosconsole.conf"/>
  <!-- Gazebo world to load -->
  <arg name="world" default="$(find vrx_gazebo)/worlds/example_course.world" />
  <!-- If true, run gazebo GUI -->
  <arg name="gui" default="true" />
  <!-- If true, run gazebo in verbose mode -->
  <arg name="verbose" default="false"/>
  <!-- If true, start in paused state -->
  <arg name="paused" default="false"/>
  <!-- Set various other gazebo arguments-->
  <arg name="extra_gazebo_args" default=""/>
  <!-- Start in a default namespace -->
  <arg name="namespace" default="wamv"/>

  <!-- Initial USV location and attitude-->
  <arg name="x" default="158" />
  <arg name="y" default="108" />
  <arg name="z" default="0.1" />
  <arg name="P" default="0" />
  <arg name="R" default="0" />
  <arg name="Y" default="-2.76" />

  <!-- If true, show non-competition ROS topics (/gazebo/model_states, /vrx/debug/wind/direction, etc.)-->
  <arg name="non_competition_mode" default="true"/>
  <arg name="enable_ros_network" value="$(arg non_competition_mode)"/>
  <env name="VRX_DEBUG" value="$(arg non_competition_mode)"/>
  <env unless="$(arg non_competition_mode)" name="GAZEBO_MODEL_PATH" value="$(find vrx_gazebo)/models:$(find wamv_gazebo)/models:$(find wamv_description)/models:$(optenv GAZEBO_MODEL_PATH)"/>

  <!-- Allow user specified thruster configurations
       H = stern thrusters on each hull
       T = H with a lateral thruster
       X = "holonomic" configuration -->
  <arg name="thrust_config" default="H" />

  <!-- Do you want to enable sensors? -->
  <arg name="camera_enabled" default="false" />
  <arg name="gps_enabled" default="false" />
  <arg name="imu_enabled" default="false" />
  <arg name="lidar_enabled" default="false" />
  <arg name="ground_truth_enabled" default="false" />

  <!-- Start Gazebo with the world file -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(arg world)"/>
    <arg name="verbose" value="$(arg verbose)"/>
    <arg name="paused" value="$(arg paused)"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="$(arg gui)" />
    <arg name="enable_ros_network" value="$(arg enable_ros_network)"/>
    <arg name="extra_gazebo_args" value="$(arg extra_gazebo_args)"/>
  </include>

  <!-- Load robot model -->
  <arg name="urdf" default="$(find wamv_gazebo)/urdf/wamv_gazebo.urdf.xacro"/>
  <param name="$(arg namespace)/robot_description" 
         command="$(find xacro)/xacro --inorder '$(arg urdf)' 
         thruster_config:=$(arg thrust_config) 
         camera_enabled:=$(arg camera_enabled) 
         gps_enabled:=$(arg gps_enabled) 
         imu_enabled:=$(arg imu_enabled) 
         lidar_enabled:=$(arg lidar_enabled) 
         ground_truth_enabled:=$(arg ground_truth_enabled) 
         namespace:=$(arg namespace)"/>

  <!-- 添加无人机 -->
  <!-- iris_0 -->
  <group ns="iris_0">
    <!-- MAVROS and vehicle configs -->
    <arg name="ID" value="0"/>
    <arg name="ID_in_group" value="0"/>
    <arg name="fcu_url" default="udp://:24540@localhost:34580"/>
    <!-- PX4 SITL and vehicle spawn -->
    <include file="$(find px4)/launch/single_vehicle_spawn_xtd.launch">
      <arg name="x" value="170"/>
      <arg name="y" value="120"/>
      <arg name="z" value="2"/>
      <arg name="R" value="0"/>
      <arg name="P" value="0"/>
      <arg name="Y" value="0"/>
      <arg name="vehicle" value="iris"/>
      <arg name="sdf" value="iris_stereo_camera"/>
      <arg name="mavlink_udp_port" value="18570"/>
      <arg name="mavlink_tcp_port" value="4560"/>
      <arg name="udp_gimbal_port" value="13030"/>
      <arg name="ID" value="$(arg ID)"/>
      <arg name="ID_in_group" value="$(arg ID_in_group)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
      <arg name="fcu_url" value="$(arg fcu_url)"/>
      <arg name="gcs_url" value=""/>
      <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
      <arg name="tgt_component" value="1"/>
    </include>
  </group>

  <!-- iris_1 -->
  <group ns="iris_1">
    <!-- MAVROS and vehicle configs -->
    <arg name="ID" value="1"/>
    <arg name="ID_in_group" value="1"/>
    <arg name="fcu_url" default="udp://:24541@localhost:34581"/>
    <!-- PX4 SITL and vehicle spawn -->
    <include file="$(find px4)/launch/single_vehicle_spawn_xtd.launch">
      <arg name="x" value="170"/>
      <arg name="y" value="116"/>
      <arg name="z" value="2"/>
      <arg name="R" value="0"/>
      <arg name="P" value="0"/>
      <arg name="Y" value="0"/>
      <arg name="vehicle" value="iris"/>
      <arg name="sdf" value="iris_stereo_camera"/>
      <arg name="mavlink_udp_port" value="18571"/>
      <arg name="mavlink_tcp_port" value="4561"/>
      <arg name="udp_gimbal_port" value="13031"/>
      <arg name="ID" value="$(arg ID)"/>
      <arg name="ID_in_group" value="$(arg ID_in_group)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
      <arg name="fcu_url" value="$(arg fcu_url)"/>
      <arg name="gcs_url" value=""/>
      <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
      <arg name="tgt_component" value="1"/>
    </include>
  </group>

  <!-- iris_2 -->
  <group ns="iris_2">
    <!-- MAVROS and vehicle configs -->
    <arg name="ID" value="2"/>
    <arg name="ID_in_group" value="2"/>
    <arg name="fcu_url" default="udp://:24542@localhost:34582"/>
    <!-- PX4 SITL and vehicle spawn -->
    <include file="$(find px4)/launch/single_vehicle_spawn_xtd.launch">
      <arg name="x" value="172"/>
      <arg name="y" value="120"/>
      <arg name="z" value="2"/>
      <arg name="R" value="0"/>
      <arg name="P" value="0"/>
      <arg name="Y" value="0"/>
      <arg name="vehicle" value="iris"/>
      <arg name="sdf" value="iris_stereo_camera"/>
      <arg name="mavlink_udp_port" value="18572"/>
      <arg name="mavlink_tcp_port" value="4562"/>
      <arg name="udp_gimbal_port" value="13032"/>
      <arg name="ID" value="$(arg ID)"/>
      <arg name="ID_in_group" value="$(arg ID_in_group)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
      <arg name="fcu_url" value="$(arg fcu_url)"/>
      <arg name="gcs_url" value=""/>
      <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
      <arg name="tgt_component" value="1"/>
    </include>
  </group>

  <!-- iris_3 -->
  <group ns="iris_3">
    <!-- MAVROS and vehicle configs -->
    <arg name="ID" value="3"/>
    <arg name="ID_in_group" value="3"/>
    <arg name="fcu_url" default="udp://:24543@localhost:34583"/>
    <!-- PX4 SITL and vehicle spawn -->
    <include file="$(find px4)/launch/single_vehicle_spawn_xtd.launch">
      <arg name="x" value="172"/>
      <arg name="y" value="116"/>
      <arg name="z" value="2"/>
      <arg name="R" value="0"/>
      <arg name="P" value="0"/>
      <arg name="Y" value="0"/>
      <arg name="vehicle" value="iris"/>
      <arg name="sdf" value="iris_stereo_camera"/>
      <arg name="mavlink_udp_port" value="18573"/>
      <arg name="mavlink_tcp_port" value="4563"/>
      <arg name="udp_gimbal_port" value="13033"/>
      <arg name="ID" value="$(arg ID)"/>
      <arg name="ID_in_group" value="$(arg ID_in_group)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
      <arg name="fcu_url" value="$(arg fcu_url)"/>
      <arg name="gcs_url" value=""/>
      <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
      <arg name="tgt_component" value="1"/>
    </include>
  </group>

  <!-- iris_4 -->
  <group ns="iris_4">
    <!-- MAVROS and vehicle configs -->
    <arg name="ID" value="4"/>
    <arg name="ID_in_group" value="4"/>
    <arg name="fcu_url" default="udp://:24544@localhost:34584"/>
    <!-- PX4 SITL and vehicle spawn -->
    <include file="$(find px4)/launch/single_vehicle_spawn_xtd.launch">
      <arg name="x" value="174"/>
      <arg name="y" value="120"/>
      <arg name="z" value="2"/>
      <arg name="R" value="0"/>
      <arg name="P" value="0"/>
      <arg name="Y" value="0"/>
      <arg name="vehicle" value="iris"/>
      <arg name="sdf" value="iris_stereo_camera"/>
      <arg name="mavlink_udp_port" value="18574"/>
      <arg name="mavlink_tcp_port" value="4564"/>
      <arg name="udp_gimbal_port" value="13034"/>
      <arg name="ID" value="$(arg ID)"/>
      <arg name="ID_in_group" value="$(arg ID_in_group)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
      <arg name="fcu_url" value="$(arg fcu_url)"/>
      <arg name="gcs_url" value=""/>
      <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
      <arg name="tgt_component" value="1"/>
    </include>
  </group>

  <!-- iris_5 -->
  <group ns="iris_5">
    <!-- MAVROS and vehicle configs -->
    <arg name="ID" value="5"/>
    <arg name="ID_in_group" value="5"/>
    <arg name="fcu_url" default="udp://:24545@localhost:34585"/>
    <!-- PX4 SITL and vehicle spawn -->
    <include file="$(find px4)/launch/single_vehicle_spawn_xtd.launch">
      <arg name="x" value="174"/>
      <arg name="y" value="116"/>
      <arg name="z" value="2"/>
      <arg name="R" value="0"/>
      <arg name="P" value="0"/>
      <arg name="Y" value="0"/>
      <arg name="vehicle" value="iris"/>
      <arg name="sdf" value="iris_stereo_camera"/>
      <arg name="mavlink_udp_port" value="18575"/>
      <arg name="mavlink_tcp_port" value="4565"/>
      <arg name="udp_gimbal_port" value="13035"/>
      <arg name="ID" value="$(arg ID)"/>
      <arg name="ID_in_group" value="$(arg ID_in_group)"/>
    </include>
    <!-- MAVROS -->
    <include file="$(find mavros)/launch/px4.launch">
      <arg name="fcu_url" value="$(arg fcu_url)"/>
      <arg name="gcs_url" value=""/>
      <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
      <arg name="tgt_component" value="1"/>
    </include>
  </group>

  <!-- Spawn model in Gazebo, script depending on non_competition_mode -->
  <node name="spawn_model" pkg="gazebo_ros" type="spawn_model" if="$(arg non_competition_mode)"
        args="-x $(arg x) -y $(arg y) -z $(arg z)
              -R $(arg R) -P $(arg P) -Y $(arg Y)
              -urdf -param $(arg namespace)/robot_description -model wamv"/>

  <node name="spawn_wamv" pkg="vrx_gazebo" type="spawn_wamv.bash" unless="$(arg non_competition_mode)"
        args="-x $(arg x) -y $(arg y) -z $(arg z)
              -R $(arg R) -P $(arg P) -Y $(arg Y)
              --urdf $(arg urdf) --model wamv"/>
</launch>
 然后再次运行仿真环境启动脚本,则会发现无人机与无人船都有了
roslaunch px4 sandisland.launch

至此,包含着无人机和无人船的方正环境启动完毕。
然后推出仿真环境,并关闭启动命令运行窗口。

3 为了用键盘控制无人机,需要检查PX4飞控EKF配置,原理可参考PX4飞控EKF配置 · 语雀。

首先,运行下列命令打开rcS文件
gedit ~/PX4_Firmware/build/px4_sitl_default/etc/init.d-posix/rcS
 确保文件中的GPS部分做了如下修改(图中红框部分)

4 真正式启动仿真环境

启动gazebo仿真环境:

cd PX4_Firmware/
roslaunch px4 sandisland.launch 

启动多无人机通信脚本:

cd ~/XTDrone/communication/
bash multi_vehicle_communication.sh

启动无人机控制键盘:

cd ~/XTDrone/control/keyboard
python3 multirotor_keyboard_control.py iris 6 vel  # 根据你所启动的无人机数量来修改第二个参数

无人船控制

可以通过下面的话题来控制无人船的运动:
/wamv/thrusters/left_thrust_angle
/wamv/thrusters/left_thrust_cmd
/wamv/thrusters/right_thrust_angle
/wamv/thrusters/right_thrust_cmd
比如给左右推进器相同的推力:
rostopic pub -r 1  /wamv/thrusters/left_thrust_cmd std_msgs/Float32 "data: 1.0" 
rostopic pub -r 1  /wamv/thrusters/right_thrust_cmd std_msgs/Float32 "data: 1.0" 

5 最终的运行效果展示

说明:虽然本次启动了6架无人机,都已成功建立了通信,但最后只有四架无人机起飞,不过也没关系,不影响仿真效果。
至此,所有配置均已完成,前路漫漫,任重道远,遇到问题不要着急,逐一解决即可。

6 各功能包修改后的完整版CMakeList.txt文件

6.1 usv_gazebo_plugins

cmake_minimum_required(VERSION 3.0)
project(usv_gazebo_plugins VERSION 1.0.0)

# Set policy for CMake 3.1+. Use OLD policy to let FindBoost.cmake, dependency
# of gazebo, use quoted variables in if()
if(POLICY CMP0048)
  cmake_policy(SET CMP0048 NEW)
endif()

find_package(catkin REQUIRED COMPONENTS gazebo_dev roscpp message_generation xacro wave_gazebo_plugins usv_msgs)
find_package(Eigen3 REQUIRED)

###################################
## catkin specific configuration ##
###################################

catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS message_runtime gazebo_dev roscpp wave_gazebo_plugins
)

# Plugins require c++14

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include_directories( include
  ${catkin_INCLUDE_DIRS}
  ${EIGEN3_INCLUDE_DIRS}
)
link_directories(
  ${catkin_LIBRARY_DIRS}
)

## Declare a C++ library
add_library(buoyancy_gazebo_plugin
  src/buoyancy_gazebo_plugin.cc
  src/shape_volume.cc
  src/polyhedron_volume.cc
)
target_link_libraries(buoyancy_gazebo_plugin
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS buoyancy_gazebo_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_dynamics_plugin
  src/usv_gazebo_dynamics_plugin.cc
)
target_link_libraries(usv_gazebo_dynamics_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_dynamics_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_thrust_plugin
  src/usv_gazebo_thrust_plugin.cc
)
target_link_libraries(usv_gazebo_thrust_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_thrust_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_wind_plugin
  src/usv_gazebo_wind_plugin.cc
)
target_link_libraries(usv_gazebo_wind_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_wind_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

## Declare a C++ library
add_library(usv_gazebo_acoustic_pinger_plugin
  src/acoustic_pinger_plugin.cc
)
add_dependencies(usv_gazebo_acoustic_pinger_plugin usv_msgs_generate_messages_cpp)
target_link_libraries(usv_gazebo_acoustic_pinger_plugin
  ${catkin_LIBRARIES}
  ${Eigen_LIBRARIES}
)
install(TARGETS usv_gazebo_acoustic_pinger_plugin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

set(XACRO_INORDER)
if(DEFINED ENV{ROS_DISTRO})
  if($ENV{ROS_DISTRO} STREQUAL "kinetic")
    set(XACRO_INORDER INORDER)
  endif()
endif()

# Generate demo world files from xacro and install
xacro_add_files(
  worlds/buoyancy_plugin_demo.world.xacro
  ${XACRO_INORDER} INSTALL DESTINATION worlds
)
install(DIRECTORY worlds/
        DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/worlds)

if(CATKIN_ENABLE_TESTING)
  # buoyancy plugin test
  catkin_add_gtest(buoyancy_plugin_test test/buoyancy_test.cc)
  target_link_libraries(buoyancy_plugin_test buoyancy_gazebo_plugin)
endif()

install(DIRECTORY include/${PROJECT_NAME}/
        DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})

6.2 usv_msgs

cmake_minimum_required(VERSION 2.8.3)
project(usv_msgs)

find_package(catkin REQUIRED COMPONENTS
  message_generation
  message_runtime
  std_msgs
)

add_message_files(
   FILES
   RangeBearing.msg
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
   CATKIN_DEPENDS message_generation message_runtime std_msgs
)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

6.3  vrx_gazebo

cmake_minimum_required(VERSION 2.8.3)
project(vrx_gazebo)

# We need erb to process the .world.erb files.
find_program(ERB_EXE_PATH erb)
if(NOT ERB_EXE_PATH)
  message(FATAL_ERROR "Could not find the `erb` tool.  Try `sudo apt-get install ruby`")
endif()

# For Qt
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)

# Set policy for CMake 3.1+. Use OLD policy to let FindBoost.cmake, dependency
# of gazebo, use quoted variables in if()
if(POLICY CMP0054)
  cmake_policy(SET CMP0054 NEW)
endif()
# Use OLD policy to be able to use *_generate_services_cpp before they exist,
# without error.
if(POLICY CMP0046)
  cmake_policy(SET CMP0046 NEW)
endif()

find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Protobuf REQUIRED)
find_package(gazebo REQUIRED)

find_package(catkin REQUIRED COMPONENTS
  gazebo_dev
  geographic_msgs
  message_generation
  roscpp
  rospy
  std_msgs
  wamv_gazebo
  wave_gazebo
  xacro
)

########################
## Message generation ##
########################

add_message_files(
  FILES
  Task.msg
  Contact.msg
)

add_service_files(
  FILES
  ColorSequence.srv
)

# Python scripts setup
catkin_python_setup()

generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS wamv_gazebo wave_gazebo xacro gazebo_dev geographic_msgs std_msgs message_runtime
  LIBRARIES scoring_plugin
)

set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS} ${GAZEBO_CXX_FLAGS}") 

include_directories(include ${catkin_INCLUDE_DIRS}
  ${Qt5Core_INCLUDE_DIRS}
  ${QT_USE_FILE}
  ${GAZEBO_INCLUDE_DIRS}
  ${CMAKE_CURRENT_BINARY_DIR}/msgs
)

link_directories(${GAZEBO_LIBRARY_DIRS} ${CMAKE_CURRENT_BINARY_DIR}/msgs)
add_subdirectory(msgs)

add_definitions(${QT_DEFINITIONS})

# Library for displaying waypoint markers
add_library(waypoint_markers src/waypoint_markers.cc)
target_link_libraries(waypoint_markers ${catkin_LIBRARIES})
add_dependencies(waypoint_markers ${catkin_EXPORTED_TARGETS})
install(TARGETS waypoint_markers
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Plugin for setting color of light buoy.
add_library(light_buoy_plugin src/light_buoy_plugin.cc)
target_link_libraries(light_buoy_plugin
  ${catkin_LIBRARIES} 
  light_buoy_colors_msgs
)
add_dependencies(light_buoy_plugin ${catkin_EXPORTED_TARGETS}
  light_buoy_colors_msgs
)
install(TARGETS light_buoy_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Plugin for setting color and shape of a placard.
add_library(placard_plugin src/placard_plugin.cc)
target_link_libraries(placard_plugin
  ${catkin_LIBRARIES}
  dock_placard_msgs
)
add_dependencies(placard_plugin
  ${catkin_EXPORTED_TARGETS}
  dock_placard_msgs
)
install(TARGETS placard_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# A generic scoring plugin.
add_library(scoring_plugin src/scoring_plugin.cc)
target_link_libraries(scoring_plugin
  ${catkin_LIBRARIES}
)
add_dependencies(scoring_plugin
  ${catkin_EXPORTED_TARGETS}
  vrx_gazebo_generate_messages_cpp
  vrx_gazebo_generate_services_cpp
)
install(TARGETS scoring_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Plugin for scoring the navigation challenge task.
add_library(navigation_scoring_plugin src/navigation_scoring_plugin.cc)
target_link_libraries(navigation_scoring_plugin
  ${catkin_LIBRARIES}
  scoring_plugin)
add_dependencies(navigation_scoring_plugin ${catkin_EXPORTED_TARGETS})
install(TARGETS navigation_scoring_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Plugin for scoring the station keeping challenge task.
add_library(stationkeeping_scoring_plugin src/stationkeeping_scoring_plugin.cc)
target_link_libraries(stationkeeping_scoring_plugin
  ${catkin_LIBRARIES}
  scoring_plugin
  waypoint_markers)
add_dependencies(stationkeeping_scoring_plugin ${catkin_EXPORTED_TARGETS})
install(TARGETS stationkeeping_scoring_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Plugin for scoring the waypoint navigation challenge task.
add_library(wayfinding_scoring_plugin src/wayfinding_scoring_plugin.cc)
target_link_libraries(wayfinding_scoring_plugin
  ${catkin_LIBRARIES}
  scoring_plugin
  waypoint_markers)
add_dependencies(wayfinding_scoring_plugin ${catkin_EXPORTED_TARGETS})
install(TARGETS wayfinding_scoring_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Plugin for scoring the scan and dock task.
add_library(scan_dock_scoring_plugin src/scan_dock_scoring_plugin.cc)
target_link_libraries(scan_dock_scoring_plugin
  ${catkin_LIBRARIES}
  scoring_plugin 
  light_buoy_colors_msgs
  dock_placard_msgs
  )
add_dependencies(scan_dock_scoring_plugin
  ${catkin_EXPORTED_TARGETS}
  light_buoy_colors_msgs
  dock_placard_msgs
)
install(TARGETS scan_dock_scoring_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

if(${GAZEBO_MAJOR_VERSION} GREATER 7)
  # Plugin for Task Info GUI Overlay
  add_library(gui_task_widget SHARED ${headers_MOC}
         	src/gui_task_widget.cc
  )

  target_link_libraries(gui_task_widget 
    ${catkin_LIBRARIES}
    ${GAZEBO_LIBRARIES}
    ${PROTOBUF_LIBRARIES}
    ${QT_LIBRARIES}
  )
  qt5_use_modules(gui_task_widget Widgets)
  add_dependencies(gui_task_widget ${catkin_EXPORTED_TARGETS})
  install(TARGETS gui_task_widget
    ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
  )
endif()

# Plugin for scoring the perception task.
add_library(perception_scoring_plugin src/perception_scoring_plugin.cc)
target_link_libraries(perception_scoring_plugin
  ${catkin_LIBRARIES}
  scoring_plugin)
add_dependencies(perception_scoring_plugin ${catkin_EXPORTED_TARGETS})
install(TARGETS perception_scoring_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Dock base files that need to be processed with erb
set(dock_base_erb_files
  models/dock_2016_base/model.sdf.erb
  models/dock_2018_base/model.sdf.erb
  models/dock_2016_base_dynamic/model.sdf.erb
  models/dock_2018_base_dynamic/model.sdf.erb
)

# Dock files that need to be processed with erb
set(dock_erb_files
  models/dock_2016/model.sdf.erb
  models/dock_2018/model.sdf.erb
  models/dock_2016_dynamic/model.sdf.erb
  models/dock_2018_dynamic/model.sdf.erb
)

# Process the dock base erb files
foreach(_erb ${dock_base_erb_files})
  string(REGEX REPLACE ".sdf.erb" ".sdf" _model ${_erb})
  set(_model ${CMAKE_CURRENT_SOURCE_DIR}/${_model})
  add_custom_command(OUTPUT ${_model}
                     COMMAND ${ERB_EXE_PATH} ${_erb} > ${_model}
                     DEPENDS
                       ${CMAKE_CURRENT_SOURCE_DIR}/${_erb}
                       ${CMAKE_CURRENT_SOURCE_DIR}/dock_generator.erb
                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

  list(APPEND dock_base_files ${_model})
endforeach()
add_custom_target(dock_base_erb_generation ALL DEPENDS ${dock_base_files})

# Process the dock erb files
foreach(_erb ${dock_erb_files})
  string(REGEX REPLACE ".sdf.erb" ".sdf" _model ${_erb})
  set(_model ${CMAKE_CURRENT_SOURCE_DIR}/${_model})
  add_custom_command(OUTPUT ${_model}
                     COMMAND ${ERB_EXE_PATH} ${_erb} > ${_model}
                     DEPENDS
                       ${CMAKE_CURRENT_SOURCE_DIR}/${_erb}
                       ${CMAKE_CURRENT_SOURCE_DIR}/dock_generator.erb
                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

  list(APPEND dock_files ${_model})
endforeach()
add_custom_target(dock_erb_generation ALL
  DEPENDS
    ${dock_files}
    dock_base_erb_generation
)

set(XACRO_INORDER)
if(DEFINED ENV{ROS_DISTRO})
  if($ENV{ROS_DISTRO} STREQUAL "kinetic")
    set(XACRO_INORDER INORDER)
  endif()
endif()

# Generate world files from xacro and install
xacro_add_files(
  worlds/example_course.world.xacro
  worlds/navigation_task.world.xacro
  worlds/perception_task.world.xacro
  worlds/sandisland.world.xacro
  worlds/dock.world.xacro
  worlds/scan_and_dock.world.xacro
  worlds/stationkeeping_task.world.xacro
  worlds/wayfinding_task.world.xacro
  worlds/wind_test.world.xacro
  worlds/ocean.world.xacro
  ${XACRO_INORDER} INSTALL DESTINATION worlds
)
# Generate obstacle course
add_custom_command(
  OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/models/robotx_2018_qualifying_avoid_obstacles_buoys/model.sdf
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_avoid_obstacles_buoys
  COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_avoid_obstacles_buoys --seed 1337 --a3 6 --a5 7 --a7 7 > ${CMAKE_CURRENT_SOURCE_DIR}/models/robotx_2018_qualifying_avoid_obstacles_buoys/model.sdf
)
add_custom_target(${PROJECT_NAME}_generate_obstacle_course_buoys ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/models/robotx_2018_qualifying_avoid_obstacles_buoys/model.sdf)

# Install all the config files
install(DIRECTORY config/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/config)

# Install all the world files
install(DIRECTORY worlds/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/worlds)

# Install all the model files
install(DIRECTORY models/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/models)

# Install all the launch files
install(DIRECTORY launch/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch)

install(DIRECTORY include/
  DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.hh"
)

install(PROGRAMS scripts/spawn_wamv.bash
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})

if(CATKIN_ENABLE_TESTING)
  find_package(rostest REQUIRED)
  add_rostest_gtest(sandisland_test
                    test/sandisland.test
                    test/sandisland.cc)
  target_link_libraries(sandisland_test ${catkin_LIBRARIES})
endif()

# Python Scripts
catkin_install_python(PROGRAMS
    nodes/twist2thrust.py
    nodes/key2thrust_angle.py
    scripts/generate_worlds
    scripts/generate_wamv
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})

6.4 wamv_description

cmake_minimum_required(VERSION 2.8.3)
project(wamv_description)
find_package(catkin REQUIRED COMPONENTS xacro)
catkin_package(CATKIN_DEPENDS xacro)

set(XACRO_INORDER)
if(DEFINED ENV{ROS_DISTRO})
  if($ENV{ROS_DISTRO} STREQUAL "kinetic")
    set(XACRO_INORDER INORDER)
  endif()
endif()

xacro_add_files(
  urdf/wamv_base.urdf.xacro
    ${XACRO_INORDER} INSTALL DESTINATION urdf
)

install(DIRECTORY models/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/models)

install(DIRECTORY urdf/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/urdf)

6.5 wamv_gazebo

cmake_minimum_required(VERSION 2.8.3)
project(wamv_gazebo)

# Set policy for CMake 3.1+. Use OLD policy to let FindBoost.cmake, dependency
# of gazebo, use quoted variables in if()
if(POLICY CMP0054)
  cmake_policy(SET CMP0054 NEW)
endif()

find_package(catkin REQUIRED COMPONENTS
  wamv_description
  usv_gazebo_plugins
  xacro
)
catkin_package(
  CATKIN_DEPENDS wamv_description usv_gazebo_plugins xacro
)

set(XACRO_INORDER)
if(DEFINED ENV{ROS_DISTRO})
  if($ENV{ROS_DISTRO} STREQUAL "noetic")
    set(XACRO_INORDER INORDER)
  endif()
endif()

# Generate urdf files from xacro and install
xacro_add_files(
  urdf/wamv_gazebo.urdf.xacro
  ${XACRO_INORDER} INSTALL DESTINATION urdf
)

# Install meshes and textures
install(DIRECTORY models/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/models)

# Install xacro files / macros
install(DIRECTORY urdf/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/urdf)

# Install config files
install(DIRECTORY config/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/config)

# Install launch files
install(DIRECTORY launch/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch)

 6.6  wave_gazebo

cmake_minimum_required(VERSION 2.8.3)
project(wave_gazebo)

# We need erb to process the model erb files.
find_program(ERB_EXE_PATH erb)
if(NOT ERB_EXE_PATH)
  message(FATAL_ERROR "Could not find the `erb` tool.  Try `sudo apt-get install ruby`")
endif()

find_package(catkin REQUIRED COMPONENTS
  xacro
)

catkin_package(
  CATKIN_DEPENDS xacro
)

# Model files to be processed with erb
set (xacro_erb_files
  world_models/ocean_waves/model.xacro.erb
)
# Process the xacro erb files
foreach(_erb ${xacro_erb_files})
  string(REGEX REPLACE ".xacro.erb" ".xacro" _model ${_erb})
  set(_model ${CMAKE_CURRENT_SOURCE_DIR}/${_model})
  add_custom_command(OUTPUT ${_model}
                     COMMAND ${ERB_EXE_PATH} ${_erb} > ${_model}
                     DEPENDS
                       ${CMAKE_CURRENT_SOURCE_DIR}/${_erb}
                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

  list(APPEND model_files ${_model})
endforeach()

install(DIRECTORY world_models/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/world_models)

add_custom_target(model_erb_generation ALL
  DEPENDS
    ${model_files}
)

set(XACRO_INORDER)
if(DEFINED ENV{ROS_DISTRO})
  if($ENV{ROS_DISTRO} STREQUAL "noetic")
    set(XACRO_INORDER INORDER)
  endif()
endif()

# Generate world files from xacro and install
xacro_add_files(
  worlds/ocean.world.xacro
  worlds/ocean_buoys.world.xacro
  worlds/ocean_wamv.world.xacro
  ${XACRO_INORDER} INSTALL DESTINATION worlds
)

 6.7 wave_gazebo_plugins

cmake_minimum_required(VERSION 3.0)
project(wave_gazebo_plugins VERSION 1.0.0)

###############################################################################
# Compile as C++14, supported in ROS Noetic and newer

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Set policy for CMake 3.1+. Use NEW policy to manage version variables
if(POLICY CMP0048)
  cmake_policy(SET CMP0048 NEW)
endif()

###############################################################################
# Other dependencies...

find_package(catkin REQUIRED COMPONENTS gazebo_ros)
find_package(gazebo REQUIRED)
find_package(Eigen3 REQUIRED)

# Find OGRE and include its components (e.g., Paging)
find_package(OGRE 1.9 REQUIRED COMPONENTS Paging)

# 手动设置 Gazebo 路径
set(GAZEBO_INCLUDE_DIRS "/usr/include/gazebo-9" "/usr/include/sdformat-6.3" "/usr/include/ignition/transport4" "/usr/include/ignition/msgs1" "/usr/include/ignition/math4")
set(GAZEBO_LIBRARY_DIRS "/usr/lib/x86_64-linux-gnu/gazebo-9/plugins")

# 添加额外的 OGRE 包含路径,确保找到所需的头文件
list(APPEND OGRE_INCLUDE_DIRS "/usr/include/OGRE")
list(APPEND OGRE_INCLUDE_DIRS "/usr/include/OGRE/Paging")
# # 查找 OGRE 头文件目录
# set(OGRE_ROOT "/usr/include/OGRE")

# # 递归地获取 OGRE 目录下所有子目录
# file(GLOB_RECURSE OGRE_SUBDIRS RELATIVE ${OGRE_ROOT} ${OGRE_ROOT}/*)

# # 初始化包含目录变量
# set(OGRE_INCLUDE_DIRS ${OGRE_ROOT})

# # 将 OGRE 子目录添加到包含目录中
# foreach(SUBDIR ${OGRE_SUBDIRS})
#     if(IS_DIRECTORY "${OGRE_ROOT}/${SUBDIR}")
#         list(APPEND OGRE_INCLUDE_DIRS "${OGRE_ROOT}/${SUBDIR}")
#     endif()
# endforeach()

# # 输出包含目录(可选,供调试用)
# # message(STATUS "OGRE include directories: ${OGRE_INCLUDE_DIRS}")

# # 添加到包含目录中
# include_directories(${OGRE_INCLUDE_DIRS})


############################################################################### 
# Catkin...

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES
    Hydrodynamics
    WavefieldModelPlugin
    WavefieldVisualPlugin
    wavegauge_plugin
  DEPENDS
    gazebo_ros
)

############################################################################### 
# Libraries...

# Hydrodynamics
add_library(Hydrodynamics
  SHARED
    src/Gazebo.cc
    src/Geometry.cc
    src/PhysicalConstants.cc
    src/Physics.cc
    src/Utilities.cc
    src/Wavefield.cc
    src/WavefieldEntity.cc
)

target_include_directories(Hydrodynamics
  PRIVATE
    ${PROJECT_SOURCE_DIR}/include
    ${Boost_INCLUDE_DIRS}
    ${catkin_INCLUDE_DIRS}
    ${EIGEN3_INCLUDE_DIR}
    ${GAZEBO_INCLUDE_DIRS}   # 确保包含 Gazebo 的 include 路径
    ${OGRE_INCLUDE_DIRS}     # 确保包含 OGRE 的额外路径
)

target_link_directories(Hydrodynamics
  PRIVATE
    ${GAZEBO_LIBRARY_DIRS}  # 确保链接 Gazebo 的库路径
)

target_link_libraries(Hydrodynamics
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
)

target_compile_features(Hydrodynamics PRIVATE cxx_std_14)
target_compile_options(Hydrodynamics PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_LIBRARIES_LIST Hydrodynamics)

############################################################################### 
# Plugins...

# WavefieldModelPlugin
add_library(WavefieldModelPlugin
  SHARED
    src/WavefieldModelPlugin.cc
)

target_include_directories(WavefieldModelPlugin
  PRIVATE
    ${PROJECT_SOURCE_DIR}/include
    ${Boost_INCLUDE_DIRS}
    ${catkin_INCLUDE_DIRS}
    ${GAZEBO_INCLUDE_DIRS}
    ${OGRE_INCLUDE_DIRS}
)

target_link_directories(WavefieldModelPlugin
  PRIVATE
    ${GAZEBO_LIBRARY_DIRS}
)

target_link_libraries(WavefieldModelPlugin
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${WAVE_GAZEBO_LIBRARIES_LIST}
)

target_compile_features(WavefieldModelPlugin PRIVATE cxx_std_14)
target_compile_options(WavefieldModelPlugin PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_PLUGINS_LIST WavefieldModelPlugin)

# WavefieldVisualPlugin
add_library(WavefieldVisualPlugin
  SHARED
    src/WavefieldVisualPlugin.cc
)

target_include_directories(WavefieldVisualPlugin
  PRIVATE
    ${PROJECT_SOURCE_DIR}/include
    ${Boost_INCLUDE_DIRS}
    ${catkin_INCLUDE_DIRS}
    ${GAZEBO_INCLUDE_DIRS}
    ${OGRE_INCLUDE_DIRS}  # 确保包含 OGRE 的 include 路径
)

target_link_directories(WavefieldVisualPlugin
  PRIVATE
    ${GAZEBO_LIBRARY_DIRS}
)

target_link_libraries(WavefieldVisualPlugin
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${WAVE_GAZEBO_LIBRARIES_LIST}
  ${OGRE_LIBRARIES}  # 确保链接 OGRE 库
)

target_compile_features(WavefieldVisualPlugin PRIVATE cxx_std_14)
target_compile_options(WavefieldVisualPlugin PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_PLUGINS_LIST WavefieldVisualPlugin)

# WavegaugePlugin
add_library(wavegauge_plugin
  SHARED
    src/wavegauge_plugin.cc
)

target_include_directories(wavegauge_plugin
  PRIVATE
    ${PROJECT_SOURCE_DIR}/include
    ${Boost_INCLUDE_DIRS}
    ${catkin_INCLUDE_DIRS}
    ${GAZEBO_INCLUDE_DIRS}
)

target_link_directories(wavegauge_plugin
  PRIVATE
    ${GAZEBO_LIBRARY_DIRS}
)

target_link_libraries(wavegauge_plugin
  WavefieldModelPlugin
  ${Boost_LIBRARIES}
  ${catkin_LIBRARIES}
  ${GAZEBO_LIBRARIES}
  ${WAVE_GAZEBO_LIBRARIES_LIST}
)

add_dependencies(wavegauge_plugin WavefieldModelPlugin)

target_compile_features(wavegauge_plugin PRIVATE cxx_std_14)
target_compile_options(wavegauge_plugin PRIVATE "-Wno-unknown-pragmas")

list(APPEND WAVE_GAZEBO_PLUGINS_LIST wavegauge_plugin)

############################################################################### 
# Executables...


############################################################################### 
# Tests...

if(CATKIN_ENABLE_TESTING)

  catkin_add_gtest(UNIT_Wavefield_TEST src/Wavefield_TEST.cc)
  target_include_directories(UNIT_Wavefield_TEST
    PRIVATE
      ${PROJECT_SOURCE_DIR}/include
      ${Boost_INCLUDE_DIRS}
      ${catkin_INCLUDE_DIRS}
      ${EIGEN3_INCLUDE_DIR}
      ${GAZEBO_INCLUDE_DIRS}
  )
  target_link_directories(UNIT_Wavefield_TEST
    PRIVATE
      ${GAZEBO_LIBRARY_DIRS}
  )
  target_link_libraries(UNIT_Wavefield_TEST ${WAVE_GAZEBO_LIBRARIES_LIST})
  target_compile_features(UNIT_Wavefield_TEST PRIVATE cxx_std_14)
  target_compile_options(UNIT_Wavefield_TEST PRIVATE "-Wno-unknown-pragmas")

endif()

############################################################################### 
# Install

install(
  TARGETS
    ${WAVE_GAZEBO_LIBRARIES_LIST}
    ${WAVE_GAZEBO_PLUGINS_LIST}
    wavegauge_plugin
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(
  DIRECTORY include/${PROJECT_NAME}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.hh"
)

install(
  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.pb.*"
)
说明:在复制后,对应修改你的路径即可。另外,针对与此配置,可能有些功能包没有用到,所以有个别的CMakeList.txt就没有改到,如果编译时还出现其他报错的话,可以参照前面改错的方法去修改。

参考:无人机与无人船协同初步 · 语雀

感谢GPT!

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

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

相关文章

GD32错误调试篇:串口通讯乱码/stm32移植到GD32后串口通讯乱码等问题

本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发 向上代码兼容GD32F450ZGT6中使用 后续项目主要在下面该专栏中发布&#xff1a; https://blog.csdn.net/qq_62316532/category_12608431.html?spm1001.2014.3001.5482 感兴趣的点个关注收藏一下吧! 电机驱动开发可以跳转…

OpenFeign服务调用与负载均衡

目录 介绍使用高级特性超时控制重试机制默认HttpClient修改请求/响应报文压缩日志打印功能 相关文献 介绍 官网说明&#xff1a; Feign 是一个声明式 Web 服务客户端。它使编写 Web 服务客户端变得更加容易。要使用 Feign&#xff0c;请创建一个接口并对其进行注释。它具有可…

《OKR工作法》读书笔记

花了两个晚上的时间看完了《OKR工作法》这本书&#xff0c;谈不上有什么感想&#xff0c;因为工作后&#xff0c;其实就一直在用这种方法&#xff0c;所谓当局者迷嘛&#xff0c;习以为常也就谈不上多少新的启发。所以&#xff0c;这篇文章纯粹是一篇读书笔记&#xff0c;把我认…

Android网络性能监控方案 android线上性能监测

1 Handler消息机制 这里我不会完整的从Handler源码来分析Android的消息体系&#xff0c;而是从Handler自身的特性引申出线上卡顿监控的策略方案。 1.1 方案确认 首先当我们启动一个App的时候&#xff0c;是由AMS通知zygote进程fork出主进程&#xff0c;其中主进程的入口就是Ac…

PEI是聚醚酰亚胺(Polyetherimide)在粘接使用时使用UV胶水的优势有哪些?要注意哪些事项?

PEI是聚醚酰亚胺&#xff08;Polyetherimide&#xff09;在粘接使用时使用UV胶水的优势有哪些&#xff1f;要注意哪些事项&#xff1f; 在使用UV胶水进行聚醚酰亚胺&#xff08;Polyetherimide&#xff0c;PEI&#xff09;粘接时&#xff0c;有一些优势和注意事项&#xff1a; …

数据库物理计划执行指南

一、背景介绍 伴随信息技术地迅猛发展和应用范围地逐步扩大&#xff0c;数据库已成为企业存储与管理数据的重要工具。但数据量激增以及用户访问需求的与日剧增&#xff0c;数据库性能也将面临巨大挑战。 好在数据库物理计划执行是解决数据库性能问题的重要手段之一&#xff0…

【2024最新精简版】Kafka面试篇

文章目录 Kafka和RabbitMQ什么区别讲一讲Kafka架构你们项目中哪里用到了Kafka?为什么会选择使用Kafka? 有什么好处 ?使用Kafka如何保证消息不丢失 ?消息的重复消费问题如何解决的 ?Kafka如何保证消费的顺序性 ?Kafka的高可用机制有了解过嘛 ?Kafka实现高性能的设计有了解…

ARM32开发——GD32F4定时器查询

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录

C++设计模式——Proxy代理模式

一&#xff0c;代理模式简介 代理模式是一种 结构型设计模式&#xff0c;该模式通过引入一个新的代理对象Proxy&#xff0c;来间接访问原始对象&#xff0c;从而使访问方式变得灵活和可控。 代理对象的设定减少了客户端与真实对象之间的直接交互。 通过引入代理对象来间接访问原…

【CVPR2024】面向StableDiffusion的编辑算法FreePromptEditing,提升图像编辑效果

近日&#xff0c;阿里云人工智能平台PAI与华南理工大学贾奎教授团队合作在深度学习顶级会议 CVPR2024 上发表 FPE(Free-Prompt-Editing) 算法&#xff0c;这是一种面向StableDiffusion的图像编辑算法。在这篇论文中&#xff0c;StableDiffusion可用于实现图像编辑的本质被挖掘&…

贪心算法——赶作业(C++)

慢慢来&#xff0c;沉稳一点。 2024年6月18日 题目描述 A同学有n份作业要做&#xff0c;每份作业有一个最后期限&#xff0c;如果在最后期限后交作业就会扣分&#xff0c;现在假设完成每份作业都需要一天。A同学想安排作业顺序&#xff0c;把扣分降到最低&#xff0c;请帮他实…

华为OD机试 - 聚餐地点 - 广度优先搜索BFS(Java 2024 D卷 200分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

美联储的秘密议程 Fed's Hidden Agenda

编译 | 刘教链 教链按&#xff1a;本文是来自“米塞斯学院”Ryan McMaken的稿子&#xff0c;原标题是「美联储“软着陆”叙事背后的真实故事&#xff08;The Real Story Behind the Fed’s “Soft Landing” Narrative&#xff09;」。昨{2024.6.17内参&#xff1a;战报会骗人&…

实验1_配置标准IPv4 ACL

1、实验目的 通过本实验可以掌握&#xff1a; IPv4 ACL工作方式和工作过程定义编号和命名的标准IPv4 ACL的方法接口和VTY下应用标准IPv4 ACL的方法 2、实验拓扑 配置IPv4 ACL的实验拓扑如图9-2所示 配置 ACL 实验拓扑如下图所示。本实验中&#xff0c;通过配置标准 ACL 实现…

无痛接入图像生成风格迁移能力:GAN生成对抗网络

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

QT基础 - 布局管理器间隔控件

目录 一. QVBoxLayout 二. QHBoxLayout 三. QGridLayout 四. QFormLayout 五. Spacers 六.总结 一. QVBoxLayout QVBoxLayout 主要用于将控件在垂直方向上进行排列。 它具有以下特点&#xff1a; 可以方便地管理和组织控件&#xff0c;使其按照垂直顺序依次排列。能够自动…

视频批量剪辑利器:轻松掌握尺寸修改技巧,支持自定义及预设尺寸,提升剪辑效率!

在数字化时代&#xff0c;视频已经成为我们生活中不可或缺的一部分。无论是社交媒体上的短视频&#xff0c;还是公司宣传的长视频&#xff0c;都离不开精心剪辑与处理。然而&#xff0c;对于很多小伙伴来说&#xff0c;视频剪辑仍然是一项既耗时又耗力的任务。尤其是当需要处理…

算法训练营第六十天(延长12天添加图论) | LeetCode 647 回文子串、LeetCode 516 最长回文子序列

LeetCode 67 回文子串 思路很简单&#xff0c;每一个dp[i]等于dp[i-1]加上当前字符向前直到0各个长度字符串回文串个数即可 代码如下&#xff1a; class Solution {public boolean isValid(String s) {int l 0, r s.length() - 1;while (l < r) {if (s.charAt(l) ! s.ch…

钡铼技术BL104在环境监测站多协议采集保障数据全面准确

随着工业化和城市化进程的加快&#xff0c;环境污染问题日益严重&#xff0c;环境监测站在保护生态环境、保障公众健康中的作用变得越来越重要。钡铼技术PLC物联网关BL104&#xff0c;为环境监测站提供了一种高效、可靠的多协议数据采集解决方案&#xff0c;保障了监测数据的全…

Multisim软件仿真之频谱分析仪

网络上有很多Multisim文件&#xff0c;有些是不能复现的&#xff0c;比如频谱仪&#xff0c;按照下面链接去操作&#xff0c;怎么也测试不出来波形&#xff0c;multisim频谱仪使用_multisim输入输出端口-CSDN博客。 原因分析&#xff1a; 1、博主设置参数未讲全&#xff0c;按…