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

2390 高校实验室预约系统JSP【程序源码+文档+调试运行】
摘要 本文介绍了一个高校实验室预约系统的设计和实现。该系统包括管理员、教师和学生三种用户,具有基础数据管理、学生管理、教师管理、系统公告管理、实验室管理、实验室预约管理和系统管理等模块。通过数据库设计和界面设计,实现了用户友好的操作体验…...

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

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

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

4.HTML网页开发的工具
4. 网页开发的工具 4.1 快捷键 4.1.1 快速复制一行 快捷键:shiftalt下箭头(上箭头) 或者ctrlc 然后 ctrlv 4.1.2 选定多个相同的单词 快捷键: ctrld 4.1.3 添加多个光标 快捷键:ctrlalt上箭头(下箭头&…...
【Qt5 VS2019 (C++)编译报错解决】ASSERT failure in QList<T>::at: “index out of range“
Qt编译报错提示: 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);原因: QList的索引越界,超…...
linux环境安装redis,以及常用的操作
1. 下载安装文件 http://download.redis.io/releases/redis-5.0.7.tar.gz 2. 把安装文件上传到 /usr/local/ 目录,并解压缩 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.断言工厂 我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件 例如Path/user/**是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoute…...

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

【多线程 - 03、线程的生命周期】
生命周期 当线程被创建并启动以后,它不是一启动就进入执行状态,也不会一直处于执行状态,而是会经历五种状态。 线程状态的五个阶段: 新建状态(New)就绪状态(Runnable)运行状态&…...

excel表的筛选后自动求和
一般都使用subtotal函数。 通过看一个大佬的视频,发现可以有更简单的方法。 首先任意筛选数据(ctrlshiftl), 然后选中需要求和的列的最下方的空白单元格,再按alt。 回车即可。 实质它还是用的subtotal函数...
2311rust特征
Rust无成本抽象 Rust中抽象基石是trait: 1,Trait是Rust中唯一的接口概念.多个类型可实现一个特征,事实上,可为现有类型提供新的特征实现.另一方面,想抽象未知类型时,找特征就行了. 2,与C模板一样,可静态分发特征. 3,可动态分发特征.有时确实需要间接,所以不必运行时"擦除…...

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

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

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

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

hive和spark-sql中 日期和时间相关函数 测试对比
测试版本: 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来拥有多个可变数据所有者引用循环与内存泄漏制造引用循环避免引用循环:将Rc变为Weak创建树形数据结构:带子节点的Node增加从子到父的引用可视化strong_count 和 weak_count 的改变 Rus…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...