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.11


SUMMARY
========

PARAMETERS
 * /rosdistro: melodic
 * /rosversion: 1.14.11

NODES

auto-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_level


contacting 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/Twist

Publishers: 
 * /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.0
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 0.0
---
linear: 
  x: 0.0
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: -2.0
---
  • rostopic pub 话题名 消息类型 消息值 手动发布一个话题消息
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist "linear:
    x: 1.0
    y: 1.0
    z: 0.0
angular:
    x: 0.0
    y: 0.0
    z: 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.0
    y: 1.0
    z: 0.0
angular:
    x: 0.0
    y: 0.0
    z: 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 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 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
    └── communication

46 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 COMPONENTS
  roscpp
  rospy
  std_msg
  message_generation
)

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

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

(3)加入新的消息类型

 add_message_files(
   FILES
   test_msg.msg
 )

(4)添加生成消息

generate_messages(
   DEPENDENCIES
   std_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,队列长度为10
		ros::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(
  FILES
  add.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 server
    ros::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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

html菜单的基本制作

前面写过一点网页菜单的博文&#xff1b;下面再复习一些技术要点&#xff1b; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.…

[工业自动化-17]:西门子S7-15xxx编程 - 软件编程 - PLC编程语言以及与嵌入式编程的比较

目录 一、博图编程语言 1.1 概述 1.2 三种编程语言之间的关系 二、PLC与嵌入式系统的类比 三、PLC编程与嵌入式系统编程的比较 3.1 不同点 3.2 相同点 3.3 PLC是一种专门用于工业控制系统的嵌入式系统 一、博图编程语言 1.1 概述 西门子&#xff08;Siemens&#xff0…

RT-Thread:嵌入式实时操作系统的设计与应用

RT-Thread&#xff08;Real-Time Thread&#xff09;是一个开源的嵌入式实时操作系统&#xff0c;其设计和应用在嵌入式领域具有重要意义。本文将从RT-Thread的设计理念、核心特性&#xff0c;以及在嵌入式系统中的应用等方面进行探讨&#xff0c;对其进行全面的介绍。 首先&a…

c语言实现两个有序链表的合并

合并两个有序链表是c语言数据结构中比较经典的问题&#xff0c;首先两个链表都是有序的&#xff0c;即节点的顺序是按照各个节点中的值从小到大排序&#xff0c;而且合并之后的新链表中的各个节点顺序也要满足从小到大的排序&#xff0c;具体如下图所示。 思路&#xff1a;用ma…

springboot国际化

1.环境配置 这里插入图片描述](https://img-blog.csdnimg.cn/024d6bc95623485eb6da4d998a892458.png) 2.文件配置 第一个默认环境 第二个英文环境 第三个中文环境 3.变量配置 调整语言 原理&#xff1a; 找到MessageSourceAutoConfiguration 中的 利用代碼的方式獲取国…

GetSimple CMS忘记密码

GetSimple CMS是一个超简单的 CMS&#xff0c;适合建立个人网站等只需要极少数页面的网站。在站上百科上&#xff0c;是这么说的&#xff1a; GetSimple是一款基于XML存储数据的开源内容管理系统&#xff0c;且易于安装和定制&#xff0c;无需MySQL支持。提供撤销保护和备份功能…

阿里云OSS和腾讯云COS对象存储介绍和简单使用

对象存储指的是一种云存储服务&#xff0c;其主要是将数据以对象的形式存储在云端&#xff0c;并且提供了完全的API调用&#xff0c;这些API包括上传&#xff0c;下载&#xff0c;删除&#xff0c;复制&#xff0c;预览&#xff0c;权限设置等等。OSS对象存储和COS对象存储都是…

图像相似度对比方法

1.哈希方法&#xff0c;其中包括均值哈希、插值哈希、感知哈希方法。计算出图片的哈希值&#xff0c;一般使用汉明 距离计算两个图片间的差距。 2.直方图算法&#xff0c;其中包括灰度直方图算法&#xff0c;RGB直方图算法&#xff0c; 3.灰度图算法&#xff1a;MSE、SSIM、…

echarts图从隐藏到显示以后大小有问题的解决方法

大家好&#xff0c;我是南宫。 今天分享一个刚刚解决的问题。 稍微介绍一下问题的背景&#xff1a; 我有一个绘制柱状图的需求&#xff0c;之前已经画好了&#xff0c;没想到今天对接数据的时候发现&#xff0c;如果没有数据&#xff0c;后端是直接返回一个空数组的。&#…

Linux系统编程——实现cp指令(应用)

cp指令格式 cp [原文件] [目标文件] cp 1.c 2.c 功能是将原文件1.c复制后并改名成2.c(内容相同&#xff0c;实现拷贝) 这里需要引入main函数的参数解读&#xff1a; 我们在定义函数时许多都带有参数&#xff0c;输入参数后便可进行定义函数内的功能执行&#xff0c;而main…

终止进程后,GPU显存仍被占用问题 | kill -9彻底杀死进程 | ps aux|grep python

本文部分内容参考博客&#xff0c;十分感谢&#xff01;&#xff01;&#xff01; 问题描述&#xff1a;在Linux终端把进程终止后&#xff0c;发现显存没有被释放出来&#xff01; ---------------------------------------------------------------------------------------F…

【java:牛客每日三十题总结-5】

java:牛客每日三十题总结 总结如下 总结如下 -Xmx&#xff1a;最大堆大小 -Xms&#xff1a;初始堆大小 -Xmn:年轻代大小 -XXSurvivorRatio&#xff1a;年轻代中Eden区与Survivor区的大小比值 年轻代5120m&#xff0c; Eden&#xff1a;Survivor3&#xff0c;Survivor区大小102…

No185.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

爬虫项目(12):正则、多线程抓取腾讯动漫,Flask展示数据

文章目录 书籍推荐正则抓取腾讯动漫数据Flask展示数据 书籍推荐 如果你对Python网络爬虫感兴趣&#xff0c;强烈推荐你阅读《Python网络爬虫入门到实战》。这本书详细介绍了Python网络爬虫的基础知识和高级技巧&#xff0c;是每位爬虫开发者的必读之作。详细介绍见&#x1f44…

使用python电脑轻量级控制手机—adb命令和手机投屏

文章目录 一、通过无线连接手机和电脑二、使用adb命令轻量级控制手机二、使用scrcpy控制手机 通过电脑控制手机有多种方式如appnium等&#xff0c;本文介绍的是两种轻量级的方案&#xff0c;使用adb命令刚和手机投屏。 一、通过无线连接手机和电脑 1、手机设置 开发者选项—us…

【文章阅读】Transfer learning for drug–target interaction prediction

Bioinformatics , 2023 Transfer learning for drug–target interaction prediction 本文主要是对迁移学习所使用的三种模式进行学习 &#xff0c;本文没有什么很值得细读的&#xff0c;只是介绍了三种迁移学习的方式罢了 深度迁移学习是将迁移学习应用于深度神经网络。深度迁…

体验版CorelDRAW2023矢量图话题工具

在当今数字化时代&#xff0c;图形设计已经成为了各行各业不可或缺的一部分。无论是企业的品牌标识、广告宣传&#xff0c;还是个人的插画作品、名片设计&#xff0c;都需要一个强大而多功能的设计软件来实现。而CorelDRAW正是这样一款令人惊叹的工具&#xff0c;它不仅提供了丰…

腾讯云3年轻量2核2G4M和2核4G5M服务器540元三年

腾讯云轻量应用服务器特价是有新用户限制的&#xff0c;所以阿腾云建议大家选择3年期轻量应用服务器&#xff0c;一劳永逸&#xff0c;免去续费困扰。腾讯云轻量应用服务器3年可以选择2核2G4M和2核4G5M带宽&#xff0c;3年轻量2核2G4M服务器540元&#xff0c;2核4G5M轻量应用服…

Cocos开发

harmonyOS开发 在Cocos Creator中&#xff0c;场景是一个独立的文件资源&#xff0c;可以像打开PSD文件一样在编辑器中双击打开&#xff1b; 场景文件是数据驱动工作流的核心&#xff0c;场景中包括图像资源、动画、特效以及驱动游戏逻辑和表现的脚本&#xff1b; Cocos Crea…

王道数据结构课后代码题p40 9.给定一个带表头结点的单链表,写出算法 : 按递增次序输出单链表中各结点的数据元素并释放结点 (c语言代码实现)

本题代码如下&#xff08;有注释&#xff09; void delete_min(linklist* head) {while ((*head)->next ! NULL)//循环到只剩下头节点{lnode* pre *head;//pre为元素最小结点的前驱结点指针lnode* p (*head)->next;//p为工作指针lnode* q;//指向被删除的结点while (p-…