当前位置: 首页 > news >正文

ROS基础知识复习

【置顶】感谢参考:https://zhuanlan.zhihu.com/p/662074088

0.背景

工作一年多没有做 ROS 相关的开发了,最近找工作想做回这一块来,根据参考内容,抽时间给这边的基础知识敲一遍复习一下

1.环境检查

打开了之前的笔记本,Ubuntu 系统及 ros 环境都还在,这边就不做环境配置了
运行一下小乌龟检查一下环境:

  • 启动 roscore
roscore
... logging to /home/livvedia/.ros/log/a62ba306-8050-11ee-98d2-d07e354f2c70/roslaunch-livvedia-7447-4219.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.started roslaunch server http://livvedia-7447:35877/
ros_comm version 1.14.11SUMMARY
========PARAMETERS* /rosdistro: melodic* /rosversion: 1.14.11NODESauto-starting new master
process[master]: started with pid [4229]
ROS_MASTER_URI=http://livvedia-7447:11311/setting /run_id to a62ba306-8050-11ee-98d2-d07e354f2c70
process[rosout-1]: started with pid [4242]
started core service [/rosout]
  • 另一个窗口启动小乌龟图像界面节点
rosrun turtlesim turtlesim_node
[ INFO] [1699679624.841384968]: Starting turtlesim with node name /turtlesim
[ INFO] [1699679624.854296725]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
  • 再一个窗口启动小乌龟运动控制节点
rosrun turtlesim turtle_teleop_key
Reading from keyboard
---------------------------
Use arrow keys to move the turtle. 'q' to quit.

使用方向键进行控制,上下键用于前进后退,左右键用于转向。
检查环境

1.常用命令

1.1 rqt_graph 查看节点之间的联系

在这里插入图片描述
节点 teleop_turtle 发布话题 turtle1/cmd_vel
节点 turtlesim 订阅话题 turtle1/cmd_vel

1.2 rqt_plot 图形化显示话题传输的数据

在这里插入图片描述
话题 turtle1/pose 下传输的数据有:
turtle1/pose/x 小乌龟在画面中x坐标
turtle1/pose/y 小乌龟在画面中y坐标
turtle1/pose/theta 小乌龟朝向角
turtle1/pose/linear_velocity 线速度
turtle1/pose/angular_velocity 角速度

1.3 rosnode

  • rosnode list 显示当前运行的所有节点信息
rosnode list
/rosout
/teleop_turtle
/turtlesim
  • rosnode info /turtlesim 输出turtlesim节点的信息。
rosnode info /turtlesim 
--------------------------------------------------------------------------------
Node [/turtlesim]
Publications: * /rosout [rosgraph_msgs/Log]* /turtle1/color_sensor [turtlesim/Color]* /turtle1/pose [turtlesim/Pose]Subscriptions: * /turtle1/cmd_vel [geometry_msgs/Twist]Services: * /clear* /kill* /reset* /spawn* /turtle1/set_pen* /turtle1/teleport_absolute* /turtle1/teleport_relative* /turtlesim/get_loggers* /turtlesim/set_logger_levelcontacting node http://livvedia-7447:37143/ ...
Pid: 4691
Connections:* topic: /rosout* to: /rosout* direction: outbound (44969 - 127.0.0.1:43780) [26]* transport: TCPROS* topic: /turtle1/cmd_vel* to: /teleop_turtle (http://livvedia-7447:45971/)* direction: inbound (41294 - livvedia-7447:55953) [28]* transport: TCPROS

列出来这个节点发布了哪些话题,订阅了哪些话题,提供了哪些服务,还有当前的一些连接状态等信息

  • rosnode ping /turtlesim 测试节点连接 状态
rosnode ping /turtlesim
rosnode: node is [/turtlesim]
pinging /turtlesim with a timeout of 3.0s
xmlrpc reply from http://livvedia-7447:37143/	time=0.617981ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.539064ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.504971ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.994921ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.548124ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.585079ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.546932ms
xmlrpc reply from http://livvedia-7447:37143/	time=0.474930ms
  • rosnode machine 列出所有 ros 设备,主从式分布的时候会显示多个设备
 rosnode machine 
livvedia-7447

当前只有一台设备,设备名为 livvedia-7447 (哈哈哈,我8年前的笔记本)

  • rosnode machine 设备名 查看指定设备上的运行节点
rosnode machine livvedia-7447
/rosout
/teleop_turtle
/turtlesim
  • rosnode kill /turtlesim 杀死节点 turtlesim
  • rosnode cleanup /turtlesim 清空节点 turtlesim

1.4 rostopic

  • rostopic list 列出所有在使用的话题
rostopic list 
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
  • rostopic info /turtle1/cmd_vel 查看话题信息
rostopic info /turtle1/cmd_vel
Type: geometry_msgs/TwistPublishers: * /teleop_turtle (http://livvedia-7447:45971/)Subscribers: * /turtlesim (http://livvedia-7447:37143/)
  • rostopic echo /turtle1/cmd_vel 查看话题具体内容
rostopic echo /turtle1/cmd_vel
linear: x: 2.0y: 0.0z: 0.0
angular: x: 0.0y: 0.0z: 0.0
---
linear: x: 0.0y: 0.0z: 0.0
angular: x: 0.0y: 0.0z: -2.0
---
  • rostopic pub 话题名 消息类型 消息值 手动发布一个话题消息
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist "linear:x: 1.0y: 1.0z: 0.0
angular:x: 0.0y: 0.0z: 1.0
"
publishing and latching message. Press ctrl-C to terminate

可以添加参数 -r 来控制发布的频率,如 -r 1 表示 1 s 发送一次

rostopic pub /turtle1/cmd_vel geometry_msgs/Twist  -r 1 "linear:x: 1.0y: 1.0z: 0.0
angular:x: 0.0y: 0.0z: 1.0
"

执行上述发布命令后,小乌龟会自动画圆
在这里插入图片描述

1.5 rosservice

  • rosservice list 列出所有服务
 rosservice list 
/clear
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/teleop_turtle/get_loggers
/teleop_turtle/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/get_loggers
/turtlesim/set_logger_level
  • rosservice info /spawn 查看服务 spawn 详细信息
rosservice info /spawn 
Node: /turtlesim
URI: rosrpc://livvedia-7447:42833
Type: turtlesim/Spawn
Args: x y theta name
  • rosservice call /spawn Args… 手动调用服务 spawn (生成小乌龟)
rosservice call /spawn "x: 10.0
y: 10.0
theta: 0.0
name: "turtle2"
"

在这里插入图片描述
右上角生成了个新乌龟 turtle2
注意:输入命令时,要在如x:后加空格,否则会报错。上面的name可以用单引号,也可以用双引号。

1.6 rosmsg

  • rosmsg show geometry_msgs/Twist 查看消息 geometry_msgs/Twist 具体定义
rosmsg show geometry_msgs/Twist
geometry_msgs/Vector3 linearfloat64 xfloat64 yfloat64 z
geometry_msgs/Vector3 angularfloat64 xfloat64 yfloat64 z
  • rosmsg packages 列出包含消息的所有包
rosmsg packages
actionlib
actionlib_msgs
actionlib_tutorials
base_local_planner
bond
cartographer_ros_msgs
control_msgs
controller_manager_msgs
costmap_2d
diagnostic_msgs
dynamic_reconfigure
farryn_controller
gazebo_msgs
gazebo_video_monitor_msgs

1.7 rosparam

  • rosparam list 列出所有参数
rosparam list 
/rosdistro
/roslaunch/uris/host_livvedia_7447__35877
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r
  • rosparam get /turtlesim/background_r 获取参数 /turtlesim/background_r 的值
  • rosparam set /turtlesim/background_r 100 将参数 /turtlesim/background_r 设置为 255,重新启动 turtlesim 节点就好发现背景颜色发生了改变

2.话题通信实现(topic)

  • 工作空间准备
mkdir -r ros_review/src/communication
cd ros_review/src
catkin_init_workspace
Creating symlink "/home/livvedia/ros_review/src/CMakeLists.txt" pointing to "/opt/ros/melodic/share/catkin/cmake/toplevel.cmake"~/ros_review$ tree
.
└── src├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake└── communication

自动生成了个 CMakeLists.txt 文件,软链接到 ros 安装目录下的一个 cmake 文件

  • 编译工作空间
catkin_make
Base path: /home/livvedia/ros_review
Source space: /home/livvedia/ros_review/src
Build space: /home/livvedia/ros_review/build
Devel space: /home/livvedia/ros_review/devel
Install space: /home/livvedia/ros_review/install
####
#### Running command: "cmake /home/livvedia/ros_review/src -DCATKIN_DEVEL_PREFIX=/home/livvedia/ros_review/devel -DCMAKE_INSTALL_PREFIX=/home/livvedia/ros_review/install -G Unix Makefiles" in "/home/livvedia/ros_review/build"
####
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using CATKIN_DEVEL_PREFIX: /home/livvedia/ros_review/devel
-- Using CMAKE_PREFIX_PATH: /home/livvedia/car_arm_ws/devel;/home/livvedia/ARM/devel;/home/livvedia/wpr1/devel;/opt/ros/melodic
-- This workspace overlays: /home/livvedia/car_arm_ws/devel;/home/livvedia/ARM/devel;/home/livvedia/wpr1/devel;/opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/livvedia/ros_review/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.29
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- Configuring done
-- Generating done
-- Build files have been written to: /home/livvedia/ros_review/build
####
#### Running command: "make -j4 -l4" in "/home/livvedia/ros_review/build"
####

检查编译后的文件目录

tree
.
├── build
│   ├── atomic_configure
│   │   ├── env.sh
│   │   ├── local_setup.bash
│   │   ├── local_setup.sh
│   │   ├── local_setup.zsh
│   │   ├── setup.bash
│   │   ├── setup.sh
│   │   ├── _setup_util.py
│   │   └── setup.zsh
│   ├── catkin
│   │   └── catkin_generated
│   │       └── version
│   │           └── package.cmake
│   ├── catkin_generated
│   │   ├── env_cached.sh
│   │   ├── generate_cached_setup.py
│   │   ├── installspace
│   │   │   ├── env.sh
│   │   │   ├── local_setup.bash
│   │   │   ├── local_setup.sh
│   │   │   ├── local_setup.zsh
│   │   │   ├── setup.bash
│   │   │   ├── setup.sh
│   │   │   ├── _setup_util.py
│   │   │   └── setup.zsh
│   │   ├── order_packages.cmake
│   │   ├── order_packages.py
│   │   ├── setup_cached.sh
│   │   └── stamps
│   │       └── Project
│   │           ├── interrogate_setup_dot_py.py.stamp
│   │           ├── order_packages.cmake.em.stamp
│   │           ├── package.xml.stamp
│   │           └── _setup_util.py.stamp
│   ├── CATKIN_IGNORE
│   ├── catkin_make.cache
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.10.2
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── clean_test_results.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── DependInfo.cmake
│   │   │   └── progress.make
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeError.log
│   │   ├── CMakeOutput.log
│   │   ├── CMakeRuleHashes.txt
│   │   ├── CMakeTmp
│   │   ├── download_extra_data.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── DependInfo.cmake
│   │   │   └── progress.make
│   │   ├── doxygen.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── DependInfo.cmake
│   │   │   └── progress.make
│   │   ├── feature_tests.bin
│   │   ├── feature_tests.c
│   │   ├── feature_tests.cxx
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   ├── run_tests.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── DependInfo.cmake
│   │   │   └── progress.make
│   │   ├── TargetDirectories.txt
│   │   └── tests.dir
│   │       ├── build.make
│   │       ├── cmake_clean.cmake
│   │       ├── DependInfo.cmake
│   │       └── progress.make
│   ├── cmake_install.cmake
│   ├── CTestConfiguration.ini
│   ├── CTestCustom.cmake
│   ├── CTestTestfile.cmake
│   ├── gtest
│   │   ├── CMakeFiles
│   │   │   ├── CMakeDirectoryInformation.cmake
│   │   │   └── progress.marks
│   │   ├── cmake_install.cmake
│   │   ├── CTestTestfile.cmake
│   │   ├── googlemock
│   │   │   ├── CMakeFiles
│   │   │   │   ├── CMakeDirectoryInformation.cmake
│   │   │   │   ├── gmock.dir
│   │   │   │   │   ├── __
│   │   │   │   │   │   └── googletest
│   │   │   │   │   │       └── src
│   │   │   │   │   ├── build.make
│   │   │   │   │   ├── cmake_clean.cmake
│   │   │   │   │   ├── DependInfo.cmake
│   │   │   │   │   ├── depend.make
│   │   │   │   │   ├── flags.make
│   │   │   │   │   ├── link.txt
│   │   │   │   │   ├── progress.make
│   │   │   │   │   └── src
│   │   │   │   ├── gmock_main.dir
│   │   │   │   │   ├── __
│   │   │   │   │   │   └── googletest
│   │   │   │   │   │       └── src
│   │   │   │   │   ├── build.make
│   │   │   │   │   ├── cmake_clean.cmake
│   │   │   │   │   ├── DependInfo.cmake
│   │   │   │   │   ├── depend.make
│   │   │   │   │   ├── flags.make
│   │   │   │   │   ├── link.txt
│   │   │   │   │   ├── progress.make
│   │   │   │   │   └── src
│   │   │   │   └── progress.marks
│   │   │   ├── cmake_install.cmake
│   │   │   ├── CTestTestfile.cmake
│   │   │   ├── gtest
│   │   │   │   ├── CMakeFiles
│   │   │   │   │   ├── CMakeDirectoryInformation.cmake
│   │   │   │   │   ├── gtest.dir
│   │   │   │   │   │   ├── build.make
│   │   │   │   │   │   ├── cmake_clean.cmake
│   │   │   │   │   │   ├── DependInfo.cmake
│   │   │   │   │   │   ├── depend.make
│   │   │   │   │   │   ├── flags.make
│   │   │   │   │   │   ├── link.txt
│   │   │   │   │   │   ├── progress.make
│   │   │   │   │   │   └── src
│   │   │   │   │   ├── gtest_main.dir
│   │   │   │   │   │   ├── build.make
│   │   │   │   │   │   ├── cmake_clean.cmake
│   │   │   │   │   │   ├── DependInfo.cmake
│   │   │   │   │   │   ├── depend.make
│   │   │   │   │   │   ├── flags.make
│   │   │   │   │   │   ├── link.txt
│   │   │   │   │   │   ├── progress.make
│   │   │   │   │   │   └── src
│   │   │   │   │   └── progress.marks
│   │   │   │   ├── cmake_install.cmake
│   │   │   │   ├── CTestTestfile.cmake
│   │   │   │   └── Makefile
│   │   │   └── Makefile
│   │   └── Makefile
│   ├── Makefile
│   └── test_results
├── devel
│   ├── cmake.lock
│   ├── env.sh
│   ├── lib
│   ├── local_setup.bash
│   ├── local_setup.sh
│   ├── local_setup.zsh
│   ├── setup.bash
│   ├── setup.sh
│   ├── _setup_util.py
│   └── setup.zsh
└── src├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake└── communication46 directories, 128 files

编译后出现了 build 和 devel 目录
build:编译空间,用来存储工作空间编译过程中产生的中间文件(文件夹里面还有 gtest 这是之前没注意到的)
devel:开发空间,用来保存编译生成的可执行文件

需要将 devel/setup.bash 添加到环境变量中才能在终端中找到这个工作空间中的功能包
两种方式:
(1)在终端中 source 一下这个文件

source  ~/ros_review/devel/setup.bash

只对当前终端生效,每次新打开终端的时候都要运行一下
(2)将 source ~/ros_review/devel/setup.bash 其添加到 bashrc 文件中

  • 创建功能包
~/ros_review/src$ catkin_create_pkg communication_basic std_msg roscpp rospy
Created file communication_basic/package.xml
Created file communication_basic/CMakeLists.txt
Created folder communication_basic/include/communication_basic
Created folder communication_basic/src
Successfully created files in /home/livvedia/ros_review/src/communication_basic. Please adjust the values in package.xml.~/ros_review/src$ tree
.
├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
└── communication_basic├── CMakeLists.txt├── include│   └── communication_basic├── package.xml└── src
  • 创建消息类型 test.msg
    位于新建文件夹 msg 内,内容如下:
cat msg/test_msg.msg 
string name
int32 age
int64 score
  • 修改 package.xml 中的内容
  1 <?xml version="1.0"?>2 <package format="2">3   <name>communication_basic</name>4   <version>0.0.0</version>5   <description>The communication_basic package</description>6 7   <!-- One maintainer tag required, multiple allowed, one person per tag -->8   <!-- Example:  -->9   <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->10   <maintainer email="livvedia@todo.todo">livvedia</maintainer>11 12 13   <!-- One license tag required, multiple allowed, one license per tag -->14   <!-- Commonly used license strings: -->15   <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->16   <license>TODO</license>17 18 19   <!-- Url tags are optional, but multiple are allowed, one per tag -->20   <!-- Optional attribute type can be: website, bugtracker, or repository -->21   <!-- Example: -->22   <!-- <url type="website">http://wiki.ros.org/communication_basic</url> -->23 24 25   <!-- Author tags are optional, multiple are allowed, one per tag -->26   <!-- Authors do not have to be maintainers, but could be -->27   <!-- Example: -->28   <!-- <author email="jane.doe@example.com">Jane Doe</author> -->29 30 31   <!-- The *depend tags are used to specify dependencies -->32   <!-- Dependencies can be catkin packages or system dependencies -->33   <!-- Examples: -->34   <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->35   <!--   <depend>roscpp</depend> -->36   <!--   Note that this is equivalent to the following: -->37   <!--   <build_depend>roscpp</build_depend> -->38   <!--   <exec_depend>roscpp</exec_depend> -->39   <!-- Use build_depend for packages you need at compile time: -->40 <build_depend>message_generation</build_depend>41   <!-- Use build_export_depend for packages you need in order to build against this package: -->42   <!--   <build_export_depend>message_generation</build_export_depend> -->43   <!-- Use buildtool_depend for build tool packages: -->44   <!--   <buildtool_depend>catkin</buildtool_depend> -->45   <!-- Use exec_depend for packages you need at runtime: -->46 <exec_depend>message_runtime</exec_depend>47   <!-- Use test_depend for packages you need only for testing: -->48   <!--   <test_depend>gtest</test_depend> -->49   <!-- Use doc_depend for packages you need only for building documentation: -->50   <!--   <doc_depend>doxygen</doc_depend> -->51   <buildtool_depend>catkin</buildtool_depend>52   <build_depend>roscpp</build_depend>53   <build_depend>rospy</build_depend>54   <build_depend>std_msg</build_depend>55   <build_export_depend>roscpp</build_export_depend>56   <build_export_depend>rospy</build_export_depend>57   <build_export_depend>std_msg</build_export_depend>58   <exec_depend>roscpp</exec_depend>59   <exec_depend>rospy</exec_depend>60   <exec_depend>std_msg</exec_depend>61 62 63   <!-- The export tag contains other, unspecified, tags -->64   <export>65     <!-- Other tools can request additional information be placed here -->66 67   </export>68 </package>

将第 40 行 和第 46 行注释去掉
<build_depend>xxx</build_depend> 标签定义了功能包中代码编译时所依赖的其他功能包
<exec_depend>xxxx</exec_depend> 标签定义了功能包中可执行程序运行时所依赖的其他功能包

  • 修改CMakeLists.txt 文件
    (1) find_package() 中加入 message_generation
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgmessage_generation
)

(2)设置运行依赖 catkin_package() 中解除注释并添加 message_runtime

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES communication_basicCATKIN_DEPENDS roscpp rospy std_msg message_runtime
#  DEPENDS system_lib
)

(3)加入新的消息类型

 add_message_files(FILEStest_msg.msg)

(4)添加生成消息

generate_messages(DEPENDENCIESstd_msgs  # Or other packages containing msgs)

(4)编译

~/ros_review$ catkin_make
Base path: /home/livvedia/ros_review
Source space: /home/livvedia/ros_review/src
Build space: /home/livvedia/ros_review/build
Devel space: /home/livvedia/ros_review/devel
Install space: /home/livvedia/ros_review/install
####
#### Running command: "make cmake_check_build_system" in "/home/livvedia/ros_review/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/livvedia/ros_review/devel
-- Using CMAKE_PREFIX_PATH: /home/livvedia/ros_review/devel;/home/livvedia/car_arm_ws/devel;/home/livvedia/ARM/devel;/home/livvedia/wpr1/devel;/opt/ros/melodic
-- This workspace overlays: /home/livvedia/ros_review/devel;/home/livvedia/car_arm_ws/devel;/home/livvedia/ARM/devel;/home/livvedia/wpr1/devel;/opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/livvedia/ros_review/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") 
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.29
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - communication_basic
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'communication_basic'
-- ==> add_subdirectory(communication_basic)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- communication_basic: 1 messages, 0 services
-- Configuring done
-- Generating done
-- Build files have been written to: /home/livvedia/ros_review/build
####
#### Running command: "make -j4 -l4" in "/home/livvedia/ros_review/build"
####
Scanning dependencies of target _communication_basic_generate_messages_check_deps_test_msg
[  0%] Built target std_msgs_generate_messages_py
[  0%] Built target std_msgs_generate_messages_nodejs
[  0%] Built target std_msgs_generate_messages_cpp
[  0%] Built target std_msgs_generate_messages_lisp
[  0%] Built target std_msgs_generate_messages_eus
[  0%] Built target _communication_basic_generate_messages_check_deps_test_msg
[ 28%] Generating Python from MSG communication_basic/test_msg
[ 28%] Generating Javascript code from communication_basic/test_msg.msg
[ 42%] Generating C++ code from communication_basic/test_msg.msg
[ 57%] Generating Lisp code from communication_basic/test_msg.msg
[ 57%] Built target communication_basic_generate_messages_nodejs
[ 71%] Generating EusLisp code from communication_basic/test_msg.msg
[ 71%] Built target communication_basic_generate_messages_lisp
[ 85%] Built target communication_basic_generate_messages_eus
[100%] Generating Python msg __init__.py for communication_basic
[100%] Built target communication_basic_generate_messages_cpp
[100%] Built target communication_basic_generate_messages_py
[100%] Built target communication_basic_generate_messages

编译后自动生成了 test_msg.h (devel/include/communication_basic 文件夹中)
使用 rosmsg show 可以查看新增的 msg 类型

~/ros_review$ rosmsg show communication_basic/test_msg
string name
int32 age
int64 score
  • 编写发布者节点
    src/publish_test.cpp 内容如下:
//发布话题:  Test_msg 
//消息类型为:communication_basic::test_msg
#include <ros/ros.h>
#include"communication_basic/test_msg.h"int main(int argc,char **argv)//argc和argv都是输入参数
{//初始化节点ros::init(argc,argv,"test_publisher");//创建句柄-管理节点资源ros::NodeHandle n;//创建一个Publisher,发布名为 Test_msg,消息类型是 communication_basic::test_msg,队列长度为10ros::Publisher test_publisher = n.advertise<communication_basic::test_msg>("Test_msg",10);//循环频率ros::Rate loop_rate(10);std::string name("tom");int age = 18;int score = 0;//roscpp会默认安装以SIGINT句柄,这句话就是用来处理由ctrl+c键盘操作、该节点被另一同名节点踢出ROS网络、ros::shutdown()被程序在某个地方调用、所有ros::NodeHandle句柄都被销毁等触发而使ros::ok()返回false值的情况while (ros::ok()){//初始化消息communication_basic::test_msg test_msg;test_msg.name = name;test_msg.age=age;test_msg.score=score++;//发布消息test_publisher.publish(test_msg);ROS_INFO("Publish test msg :[name:%s ,age:%d, score:%d]",test_msg.name.c_str(),test_msg.age,test_msg.score);//设置循环频率loop_rate.sleep();}return 0;
}
  • 编写订阅者节点
    src/subscriber.cpp 内容如下:
#include "ros/ros.h"
#include"communication_basic/test_msg.h"void TestCallback(const communication_basic::test_msg & test_msg){ROS_INFO(" name:[%s]\n", test_msg.name.c_str());ROS_INFO(" age:[%d]\n", test_msg.age);ROS_INFO(" score:[%d]\n", test_msg.score);
}int main(int argc, char** argv){ros::init(argc, argv,"test_subscriber");ros::NodeHandle n;ros::Subscriber sub = n.subscribe( "Test_msg", 1000, TestCallback);ros::spin();return 0;
}
  • 添加目标节点到 CMakeList.txt 文件中
 # 第一个参数是生成后的可执行文件名 第二个参数是源文件路径名
add_executable(test_publisher src/publisher.cpp)# 链接库
target_link_libraries(test_publisher ${catkin_LIBRARIES})add_executable(test_subscriber src/subscriber.cpp)
target_link_libraries(test_subscriber ${catkin_LIBRARIES})
  • 编译节点
~/ros_review$ catkin_make
Base path: /home/livvedia/ros_review
Source space: /home/livvedia/ros_review/src
Build space: /home/livvedia/ros_review/build
Devel space: /home/livvedia/ros_review/devel
Install space: /home/livvedia/ros_review/install
####
#### Running command: "make cmake_check_build_system" in "/home/livvedia/ros_review/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/livvedia/ros_review/devel
-- Using CMAKE_PREFIX_PATH: /home/livvedia/ros_review/devel;/home/livvedia/car_arm_ws/devel;/home/livvedia/ARM/devel;/home/livvedia/wpr1/devel;/opt/ros/melodic
-- This workspace overlays: /home/livvedia/ros_review/devel;/home/livvedia/car_arm_ws/devel;/home/livvedia/ARM/devel;/home/livvedia/wpr1/devel;/opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/livvedia/ros_review/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17") 
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.29
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - communication_basic
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'communication_basic'
-- ==> add_subdirectory(communication_basic)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- communication_basic: 1 messages, 0 services
-- Configuring done
-- Generating done
-- Build files have been written to: /home/livvedia/ros_review/build
####
#### Running command: "make -j4 -l4" in "/home/livvedia/ros_review/build"
####
[  0%] Built target std_msgs_generate_messages_cpp
[  9%] Linking CXX executable /home/livvedia/ros_review/devel/lib/communication_basic/test_subscriber
[ 18%] Linking CXX executable /home/livvedia/ros_review/devel/lib/communication_basic/test_publisher
[ 18%] Built target _communication_basic_generate_messages_check_deps_test_msg
[ 18%] Built target std_msgs_generate_messages_nodejs
[ 18%] Built target std_msgs_generate_messages_lisp
[ 18%] Built target std_msgs_generate_messages_py
[ 18%] Built target std_msgs_generate_messages_eus
[ 27%] Built target communication_basic_generate_messages_cpp
[ 45%] Built target communication_basic_generate_messages_py
[ 54%] Built target communication_basic_generate_messages_nodejs
[ 63%] Built target communication_basic_generate_messages_lisp
[ 81%] Built target communication_basic_generate_messages_eus
[ 81%] Built target communication_basic_generate_messages
[ 90%] Built target test_subscriber
[100%] Built target test_publisher
  • 运行测试

三个终端界面:

roscore
rosrun communication_basic test_publisher
rosrun communication_basic te_subscriber

结果如图:
在这里插入图片描述

3. 服务通信实现(service)

  • 新建服务消息
~/ros_review$ cat src/communication_basic/srv/add.srv 
string str1
string str2
int64 a
int64 b
---
string str_sum
  • 修改 CMakeList.txt
add_service_files(FILESadd.srv
)add_executable(add_server src/add_server.cpp)
target_link_libraries(add_server ${catkin_LIBRARIES})add_executable(add_client src/add_client.cpp)
target_link_libraries(add_client ${catkin_LIBRARIES})
  • 编写测试程序

src/add_server.cpp

#include "ros/ros.h"
#include "communication_basic/add.h"// service 回调函数 形参数据类型是固定的用引用
bool add( communication_basic::add::Request& req, communication_basic::add::Response & resp){resp.str_sum = req.str1+req.str2;resp.sum = req.a+req.b;ROS_INFO("request: a=%d, b=%d, str1=%s, str2=%s", req.a,req.b,req.str1.c_str(),req.str2.c_str());ROS_INFO("sending back response: sum=%d, str_sum=%s", resp.sum, resp.str_sum.c_str());return true;
}int main(int argc, char**argv){// ROS 节点初始化ros::init(argc,argv,"add_server");// 创建节点句柄ros::NodeHandle n;// 创建一个名为 add 的 server ,注册回调函数 add()ros::ServiceServer service = n.advertiseService("add", add);// 循环等待回调函数ROS_INFO("add server is ok");ros::spin();return 0;
}

src/add_client.cpp

#include "ros/ros.h"
#include "communication_basic/add.h"int main(int argc,char** argv){// 从终端获取两个数字和两个字符串if(argc != 5){ROS_INFO("usage:  please input 4 params(2 number 2 string), params size is:%d",argc);return 1;}//ROS 节点初始化ros::init(argc,argv,"add_client");// 创建节点句柄ros::NodeHandle n;// 创建一个 client, 请求 add serverros::ServiceClient client = n.serviceClient<communication_basic::add>("add");// 创建消息communication_basic::add test_msg;test_msg.request.a=atoll(argv[1]);test_msg.request.b=atoll(argv[2]);test_msg.request.str1=argv[3];test_msg.request.str2=argv[4];// 发布 service 请求,等待加法运算的返回结果if(client.call(test_msg)){ROS_INFO("response: sum is:%d, sum_str is:%s", test_msg.response.sum, test_msg.response.str_sum.c_str());} else{ROS_ERROR("Failed to call service add");return 1;}return 0;
}
  • 编译代码
~/ros_review$ catkin_make
Base path: /home/livvedia/ros_review
Source space: /home/livvedia/ros_review/src
Build space: /home/livvedia/ros_review/build
Devel space: /home/livvedia/ros_review/devel
Install space: /home/livvedia/ros_review/install
####
#### Running command: "make cmake_check_build_system" in "/home/livvedia/ros_review/build"
####
####
#### Running command: "make -j4 -l4" in "/home/livvedia/ros_review/build"
####
[  0%] Built target std_msgs_generate_messages_py
[  0%] Built target _communication_basic_generate_messages_check_deps_add
[  0%] Built target std_msgs_generate_messages_cpp
[  0%] Built target _communication_basic_generate_messages_check_deps_test_msg
[  0%] Built target std_msgs_generate_messages_eus
[  0%] Built target std_msgs_generate_messages_lisp
[  9%] Built target test_publisher
[ 19%] Built target test_subscriber
Scanning dependencies of target add_client
Scanning dependencies of target add_server
[ 23%] Building CXX object communication_basic/CMakeFiles/add_client.dir/src/add_client.cpp.o
[ 28%] Building CXX object communication_basic/CMakeFiles/add_server.dir/src/add_server.cpp.o
[ 47%] Built target communication_basic_generate_messages_py
[ 57%] Built target communication_basic_generate_messages_cpp
[ 57%] Built target std_msgs_generate_messages_nodejs
[ 71%] Built target communication_basic_generate_messages_eus
[ 80%] Built target communication_basic_generate_messages_nodejs
[ 90%] Built target communication_basic_generate_messages_lisp
[ 90%] Built target communication_basic_generate_messages
In file included from /opt/ros/melodic/include/ros/ros.h:40:0,from /home/livvedia/ros_review/src/communication_basic/src/add_server.cpp:1:
/home/livvedia/ros_review/src/communication_basic/src/add_server.cpp: In function ‘bool add(communication_basic::add::Request&, communication_basic::add::Response&)’:
/opt/ros/melodic/include/ros/console.h:348:176: warning: format ‘%d’ expects argument of type ‘int’, but argument 8 has type ‘communication_basic::addRequest_<std::allocator<void> >::_a_type {aka long int}[-Wformat=]location__loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)^
/opt/ros/melodic/include/ros/console.h:351:5: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER’ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(NULL, __VA_ARGS__)^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:387:7: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION’ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:572:35: note: in expansion of macro ‘ROS_LOG_COND’#define ROS_LOG(level, name, ...) ROS_LOG_COND(true, level, name, __VA_ARGS__)^~~~~~~~~~~~
/opt/ros/melodic/include/rosconsole/macros_generated.h:110:23: note: in expansion of macro ‘ROS_LOG’#define ROS_INFO(...) ROS_LOG(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)^~~~~~~
/home/livvedia/ros_review/src/communication_basic/src/add_server.cpp:9:5: note: in expansion of macro ‘ROS_INFO’ROS_INFO("request: a=%d, b=%d, str1=%s, str2=%s", req.a,req.b,req.str1.c_str(),req.str2.c_str());^~~~~~~~
/opt/ros/melodic/include/ros/console.h:348:176: warning: format ‘%d’ expects argument of type ‘int’, but argument 9 has type ‘communication_basic::addRequest_<std::allocator<void> >::_b_type {aka long int}[-Wformat=]location__loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)^
/opt/ros/melodic/include/ros/console.h:351:5: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER’ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(NULL, __VA_ARGS__)^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:387:7: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION’ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:572:35: note: in expansion of macro ‘ROS_LOG_COND’#define ROS_LOG(level, name, ...) ROS_LOG_COND(true, level, name, __VA_ARGS__)^~~~~~~~~~~~
/opt/ros/melodic/include/rosconsole/macros_generated.h:110:23: note: in expansion of macro ‘ROS_LOG’#define ROS_INFO(...) ROS_LOG(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)^~~~~~~
/home/livvedia/ros_review/src/communication_basic/src/add_server.cpp:9:5: note: in expansion of macro ‘ROS_INFO’ROS_INFO("request: a=%d, b=%d, str1=%s, str2=%s", req.a,req.b,req.str1.c_str(),req.str2.c_str());^~~~~~~~
/opt/ros/melodic/include/ros/console.h:348:176: warning: format ‘%d’ expects argument of type ‘int’, but argument 8 has type ‘communication_basic::addResponse_<std::allocator<void> >::_sum_type {aka long int}[-Wformat=]location__loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)^
/opt/ros/melodic/include/ros/console.h:351:5: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER’ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(NULL, __VA_ARGS__)^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:387:7: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION’ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:572:35: note: in expansion of macro ‘ROS_LOG_COND’#define ROS_LOG(level, name, ...) ROS_LOG_COND(true, level, name, __VA_ARGS__)^~~~~~~~~~~~
/opt/ros/melodic/include/rosconsole/macros_generated.h:110:23: note: in expansion of macro ‘ROS_LOG’#define ROS_INFO(...) ROS_LOG(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)^~~~~~~
/home/livvedia/ros_review/src/communication_basic/src/add_server.cpp:10:5: note: in expansion of macro ‘ROS_INFO’ROS_INFO("sending back response: sum=%d, str_sum=%s", resp.sum, resp.str_sum.c_str());^~~~~~~~
In file included from /opt/ros/melodic/include/ros/ros.h:40:0,from /home/livvedia/ros_review/src/communication_basic/src/add_client.cpp:1:
/home/livvedia/ros_review/src/communication_basic/src/add_client.cpp: In function ‘int main(int, char**)’:
/opt/ros/melodic/include/ros/console.h:348:176: warning: format ‘%d’ expects argument of type ‘int’, but argument 8 has type ‘communication_basic::addResponse_<std::allocator<void> >::_sum_type {aka long int}[-Wformat=]::ros::console::print(filter, __rosconsole_define_location__loc.logger_, __rosconsole_define_location__loc.level_, __FILE__, __LINE__, __ROSCONSOLE_FUNCTION__, __VA_ARGS__)^
/opt/ros/melodic/include/ros/console.h:351:5: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER’ROSCONSOLE_PRINT_AT_LOCATION_WITH_FILTER(NULL, __VA_ARGS__)^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:387:7: note: in expansion of macro ‘ROSCONSOLE_PRINT_AT_LOCATION’ROSCONSOLE_PRINT_AT_LOCATION(__VA_ARGS__); \^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/melodic/include/ros/console.h:572:35: note: in expansion of macro ‘ROS_LOG_COND’#define ROS_LOG(level, name, ...) ROS_LOG_COND(true, level, name, __VA_ARGS__)^~~~~~~~~~~~
/opt/ros/melodic/include/rosconsole/macros_generated.h:110:23: note: in expansion of macro ‘ROS_LOG’#define ROS_INFO(...) ROS_LOG(::ros::console::levels::Info, ROSCONSOLE_DEFAULT_NAME, __VA_ARGS__)^~~~~~~
/home/livvedia/ros_review/src/communication_basic/src/add_client.cpp:30:9: note: in expansion of macro ‘ROS_INFO’ROS_INFO("response: sum is:%d, sum_str is:%s", test_msg.response.sum, test_msg.response.str_sum.c_str());^~~~~~~~
[ 95%] Linking CXX executable /home/livvedia/ros_review/devel/lib/communication_basic/add_client
[100%] Linking CXX executable /home/livvedia/ros_review/devel/lib/communication_basic/add_server
[100%] Built target add_client
[100%] Built target add_server
  • 测试
    三个终端界面:
roscore
rosrun communication_basic add_server 
[ INFO] [1699810722.572002386]: add server is ok
rosrun communication_basic add_client 1 2 ab cd 
[ INFO] [1699810740.389112254]: response: sum is:3, sum_str is:abcd

相关文章:

ROS基础知识复习

【置顶】感谢参考&#xff1a;https://zhuanlan.zhihu.com/p/662074088 0.背景 工作一年多没有做 ROS 相关的开发了&#xff0c;最近找工作想做回这一块来&#xff0c;根据参考内容&#xff0c;抽时间给这边的基础知识敲一遍复习一下 1.环境检查 打开了之前的笔记本&#x…...

2390 高校实验室预约系统JSP【程序源码+文档+调试运行】

摘要 本文介绍了一个高校实验室预约系统的设计和实现。该系统包括管理员、教师和学生三种用户&#xff0c;具有基础数据管理、学生管理、教师管理、系统公告管理、实验室管理、实验室预约管理和系统管理等模块。通过数据库设计和界面设计&#xff0c;实现了用户友好的操作体验…...

C++进阶篇4---番外-红黑树

一、红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路 径会比其他路径长出俩倍&#xff0…...

《网络协议》05. 网络通信安全 · 密码技术

title: 《网络协议》05. 网络通信安全 密码技术 date: 2022-09-10 15:16:15 updated: 2023-11-12 07:03:52 categories: 学习记录&#xff1a;网络协议 excerpt: 网络通信安全&#xff08;ARP 欺骗&#xff0c;DoS & DDoS&#xff0c;SYN 洪水攻击&#xff0c;LAND 攻击&a…...

通信信道:无线信道中衰落的类型和分类

通信信道&#xff1a;无线信道中衰落的类型和分类 在进行通信系统仿真时&#xff0c;简单的情况下选择AWGN信道&#xff0c;但是AWGN信道和真是通信中的信道相差甚远&#xff0c;所以需要仿真各种其他类型的信道&#xff0c;为了更清楚理解仿真信道的特点&#xff0c;首先回顾…...

4.HTML网页开发的工具

4. 网页开发的工具 4.1 快捷键 4.1.1 快速复制一行 快捷键&#xff1a;shiftalt下箭头&#xff08;上箭头&#xff09; 或者ctrlc 然后 ctrlv 4.1.2 选定多个相同的单词 快捷键&#xff1a; ctrld 4.1.3 添加多个光标 快捷键&#xff1a;ctrlalt上箭头&#xff08;下箭头&…...

【Qt5 VS2019 (C++)编译报错解决】ASSERT failure in QList<T>::at: “index out of range“

Qt编译报错提示&#xff1a; ASSERT failure in QList<T>::at: "index out of range", file C:\Qt5\5.15.2\msvc2019_64\include\QtCore/qlist.h, line 571 //load 1st imageQFileInfo fileInfo1 list.at(2);原因&#xff1a; QList的索引越界&#xff0c;超…...

linux环境安装redis,以及常用的操作

1. 下载安装文件 http://download.redis.io/releases/redis-5.0.7.tar.gz 2. 把安装文件上传到 /usr/local/ 目录&#xff0c;并解压缩 tar -zvxf redis-5.0.7.tar.gz 3. 重命名文件夹 mv redis-5.0.7/ redis/ 4. 进入 /usr/local/redis/ 进行编译和安装 make make PREF…...

C++ Qt 学习(六):Qt http 编程

1. http 基础 HTTP 基础教程C Web 框架 drogonoatpp 2. C Qt 用户登录、注册功能实现 login_register.h #pragma once#include <QtWidgets/QDialog> #include "ui_login_register.h" #include <QNetworkReply>class login_register : public QDialog…...

38 路由的过滤器配置

3.3.断言工厂 我们在配置文件中写的断言规则只是字符串&#xff0c;这些字符串会被Predicate Factory读取并处理&#xff0c;转变为路由判断的条件 例如Path/user/**是按照路径匹配&#xff0c;这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoute…...

3分钟带你了解前端缓存-HTTP缓存

前情提要 前端缓存分为下面三大类&#xff0c;本文主要讲解HTTP缓存~ 1. HTTP缓存 强缓存协商缓存 2. 浏览器缓存 本地小容量缓存本地大容量缓存 3. 应用程序缓存 HTML5应用程序缓存 缓存作用 减少了冗余的数据传输减少服务器的负担提高了网站的性能加快加载网页速度 …...

【多线程 - 03、线程的生命周期】

生命周期 当线程被创建并启动以后&#xff0c;它不是一启动就进入执行状态&#xff0c;也不会一直处于执行状态&#xff0c;而是会经历五种状态。 线程状态的五个阶段&#xff1a; 新建状态&#xff08;New&#xff09;就绪状态&#xff08;Runnable&#xff09;运行状态&…...

excel表的筛选后自动求和

一般都使用subtotal函数。 通过看一个大佬的视频&#xff0c;发现可以有更简单的方法。 首先任意筛选数据(ctrlshiftl)&#xff0c; 然后选中需要求和的列的最下方的空白单元格&#xff0c;再按alt。 回车即可。 实质它还是用的subtotal函数...

2311rust特征

Rust无成本抽象 Rust中抽象基石是trait: 1,Trait是Rust中唯一的接口概念.多个类型可实现一个特征,事实上,可为现有类型提供新的特征实现.另一方面,想抽象未知类型时,找特征就行了. 2,与C模板一样,可静态分发特征. 3,可动态分发特征.有时确实需要间接,所以不必运行时"擦除…...

原型模式 rust和java的实现

文章目录 原型模式介绍优点缺点使用场景 实现java 实现rust 实现 rust代码仓库 原型模式 原型模式&#xff08;Prototype Pattern&#xff09;是用于创建重复的对象&#xff0c;同时又能保证性能。 这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当…...

阿里云ACK(Serverless)安装APISIX网关及APISIX Ingress Controller

在k8s上安装apisix全家&#xff0c;通过helm安装很简单&#xff0c;但是会遇到一些问题。 安装 首先登录阿里云控制台&#xff0c;在ACK集群详情页&#xff0c;进入CloudShell&#xff0c;执行下面helm命令安装apisix、apisix-ectd、apisix-dashboard和apisix-ingress-contro…...

vue+mongodb+nodejs实现表单增删改查

ExpressMongodbVue实现增删改查 效果图 前言 最近一直想学下node,毕竟会node的前端更有市场。但是光看不练&#xff0c;感觉还是少了点什么&#xff0c;就去github上看别人写的项目&#xff0c;收获颇丰&#xff0c;于是准备自己照葫芦画瓢写一个。 作为程序员&#xff0c;一…...

SpringBootWeb案例——Tlias智能学习辅助系统(3)——登录校验

前一节已经实现了部门管理、员工管理的基本功能。但并没有登录&#xff0c;就直接访问到了Tlias智能学习辅助系统的后台&#xff0c;这节来实现登录认证。 目录 登录功能登录校验(重点)会话技术会话跟踪方案一 Cookie&#xff08;客户端会话跟踪技术&#xff09;会话跟踪方案二…...

hive和spark-sql中 日期和时间相关函数 测试对比

测试版本&#xff1a; hive 2.3.4 spark 3.1.1 hadoop 2.7.7 1、增加月份 add_months(timestamp date, int months)add_months(timestamp date, bigint months)Return type: timestampusage:add_months(now(),1) 2、增加日期 adddate(timestamp startdate, int days)…...

Cell和RefCell

Cell和RefCell CellRefCellRefCell在运行时记录借用结合Rc和RefCell来拥有多个可变数据所有者引用循环与内存泄漏制造引用循环避免引用循环&#xff1a;将Rc变为Weak创建树形数据结构&#xff1a;带子节点的Node增加从子到父的引用可视化strong_count 和 weak_count 的改变 Rus…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...