ros2 launch 用法以及一些基础功能函数的示例

2024-06-03 02:44

本文主要是介绍ros2 launch 用法以及一些基础功能函数的示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • launch
    • 启动一个节点的launch示例
    • launch文件中添加节点的namespace
    • launch文件中的话题名称映射
    • launch文件中向节点内传入命令行参数
    • launch文件中向节点内传入rosparam
    • 使用方法
    • 多节点启动
    • 命令行参数配置
    • 资源重映射
    • ROS参数设置
    • 加载参数文件
    • 在launch文件中使用条件变量
    • action的分组
    • action的启动延时控制
    • Launch文件包含,在launch文件中调用另一个launch文件
    • 在launch文件中运行脚本
    • 在launch文件中设置环境变量或读取环境变量
    • launch 用法以及一些基础功能函数的示例
    • 参数文件编译配置

launch

##前言

ros2 launch文件中最主要的概念是action,ros2 launch把每一个要执行的节点,文件,脚本,功能等全部抽象成action,用统一的接口来控制其启动,最主要的结构是:

def generate_launch_description():return LaunchDescription([action_1,action_2,...action_n])

要启动的节点或其他launch文件全部都传入LaunchDescription()函数中,该函数中接受一个或多launch.actionslaunch_ros.actions类型的对象,以下列举一下常用的action:

launch_ros.actions.Node· 此函数功能是启动一个ros2节点;
launch_ros.actions.PushRosNamespace· 此函数功能是给一个节点或组设置命名空间;
launch.actions.IncludeLaunchDescription· 此函数功能是直接引用另一个launch文件;
launch.actions.SetLaunchConfiguration· 此函数功能是在launch文件内声明一个参数,并给定参数值;
launch.actions.SetEnvironmentVariable· 此函数功能是声明一个环境变量并给定环境变量的值;
launch.actions.AppendEnvironmentVariable· 此函数将对一个环境变量追加一个值,如果不存在则创建;
launch.actions.DeclareLaunchArgument· 此函数功能是声明一个启动描述参数,该参数具有名称、默认值和文档;
launch.actions.TimerAction· 此函数功能是在一段时间后执行一个或多个action;
launch.actions.GroupAction· 此函数功能是将action分组,同组内的action可以统一设定参数方便集中管理;
launch.actions.ExecuteProcess· 此函数功能是根据输入执行一个进程或脚本;
launch.actions.EmitEvent· 此函数功能是发出一个事件,触发以注册的事件函数被调用;
launch.actions.RegisterEventHandler· 此函数功能是注册一个事件;
launch.actions.UnregisterEventHandler· 此函数功能是删除一个注册过的事件;

启动一个节点的launch示例

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')])

或者:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')return LaunchDescription([action_1])

launch文件名为test.launch.py,调用launch文件启动节点:

ros2 launch ros2_test test.launch.py

launch文件中添加节点的namespace

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen',namespace='my_ros2_test')])

设置了namespace后,此节点的话题前会加上namespace的前缀,例如原来的话题名称’/test’,设置后变为’/my_ros2_test/test’

注意,有以下情况namespace无效:

节点本来就已经有了namespace了,后续会介绍将节点分组,整组节点可以设置统一的namespace,此时如果有个节点已经设置过namespace,则在此设置不会生效;
定义发布节点的时候,topic名字的前面加上了符号/;

launch文件中的话题名称映射

话题映射的字段是remappings,语法示例如下:

remappings=[('src1', 'dest1'),('src2', 'dest2'),...
]

如果需要话题名称映射的话要将该字段加入到节点的函数内,假如节点内有个test1话题要映射到test2,示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",remappings=[("test1", "test2")])])

launch文件中向节点内传入命令行参数

参数字段是arguments,语法示例如下:

arguments=['arg1', 'arg2', ...]

如果需要向ros2_test_publisher_node节点中传入命令行参数,示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",arguments=['arg1', 'arg2'])])

传入的参数可以从节点启动时main函数中的argc参数获取到参数个数,argv参数获取到参数内容,详情参考c++的命令行参数获取;

launch文件中向节点内传入rosparam

字段是parameter,语法示例如下:

parameters=[{'port': '/dev/ttyUsb0'},...
]

如果需要在launch文件中发布某个节点空间下的parameter,示例如下:

from launch import LaunchDescription
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",parameter=[{'port': '/dev/ttyUSB0'}])])

如果需要参数的值可以从外部调用launch文件时灵活更改,则可以使用变量的形式作为参数的值,在文件中给定默认值,若外部给定则以外部给定的值为准,若外部不给则以默认值为准:

port_var = LaunchConfiguration('port', default='/dev/ttyS1')

同时还可以使用DeclareLaunchArgument函数增加对参数的描述,增加描述后可以通过ros2 launch的命令行工具展示出每个launch文件中有哪些rosparam以及他的默认值和具体含义:

DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'
)

如果文件中加入了参数介绍则可以通过以下指令看到launch文件中有哪些可以自定义的参数以及参数含义:

ros2 launch ros2_test test.launch.py --show-args

所以如果launch文件中存在可配置参数,应该在LaunchDescription中添加DeclareLaunchArgument,让其他使用者明白变量名,以及他的含义是什么;

完整的launch文件如下:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfigurationdef generate_launch_description():port_var = LaunchConfiguration('port', default='/dev/ttyS1')return LaunchDescription([DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",parameter=[{'port': port_var}])])

此时我们可以把参数通过调用launch的时候传入到节点中:

ros2 launch ros2_test test.launch.py port_var:=/dev/ttyUSB2

在ros2_test_publisher_node节点中如果要想获取该参数,需要先声明parameter,然后再进行get:

this->declare_parameter<std::string>("port");
string port_str;
this->get_parameter_or<std::string>("port", port_str, "null");
if (port_str != "null") RCLCPP_INFO(this->get_logger(), "get ros2param port value : %s", port_str.c_str());

使用方法

官方推荐用python编写launch,如果launch文件不在功能包中,随便建立以.launch.py结尾的文件后,在当前目录直接运行即可,如果在功能包中可采用下面方式运行。如下代码。

ros2 launch turtlesim_mimic_launch.py  # 在文件中直接启动launch
ros2 launch <package_name> <launch_file_name> # 在功能包中启动launch

文件内容实例如下:

from launch import LaunchDescription           # launch文件的描述类
from launch_ros.actions import Node            # 节点启动的描述类def generate_launch_description():             # 自动生成launch文件的函数return LaunchDescription([                 # 返回launch文件的描述信息Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_pub', # 节点的可执行文件),Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_sub', # 节点的可执行文件名),])

多节点启动

from launch import LaunchDescription           # launch文件的描述类
from launch_ros.actions import Node            # 节点启动的描述类def generate_launch_description():             # 自动生成launch文件的函数return LaunchDescription([                 # 返回launch文件的描述信息Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_pub', # 节点的可执行文件),Node(                                  # 配置一个节点的启动package='learning_topic',          # 节点所在的功能包executable='topic_helloworld_sub', # 节点的可执行文件名),])

命令行参数配置

import osfrom ament_index_python.packages import get_package_share_directory # 查询功能包路径的方法from launch import LaunchDescription    # launch文件的描述类
from launch_ros.actions import Node     # 节点启动的描述类def generate_launch_description():      # 自动生成launch文件的函数rviz_config = os.path.join(          # 找到配置文件的完整路径get_package_share_directory('learning_launch'),'rviz','turtle_rviz.rviz')return LaunchDescription([           # 返回launch文件的描述信息Node(                             # 配置一个节点的启动package='rviz2',               # 节点所在的功能包executable='rviz2',            # 节点的可执行文件名name='rviz2',                  # 对节点重新命名arguments=['-d', rviz_config]  # 加载命令行参数)])

资源重映射

from launch import LaunchDescription      # launch文件的描述类
from launch_ros.actions import Node       # 节点启动的描述类def generate_launch_description():        # 自动生成launch文件的函数return LaunchDescription([            # 返回launch文件的描述信息Node(                             # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包namespace='turtlesim1',       # 节点所在的命名空间executable='turtlesim_node',  # 节点的可执行文件名name='sim'                    # 对节点重新命名),Node(                             # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包namespace='turtlesim2',       # 节点所在的命名空间executable='turtlesim_node',  # 节点的可执行文件名name='sim'                    # 对节点重新命名),Node(                             # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包executable='mimic',           # 节点的可执行文件名name='mimic',                 # 对节点重新命名remappings=[                  # 资源重映射列表('/input/pose', '/turtlesim1/turtle1/pose'),         # 将/input/pose话题名修改为/turtlesim1/turtle1/pose('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),  # 将/output/cmd_vel话题名修改为/turtlesim2/turtle1/cmd_vel])])

ROS参数设置

from launch import LaunchDescription                   # launch文件的描述类
from launch.actions import DeclareLaunchArgument       # 声明launch文件内使用的Argument类
from launch.substitutions import LaunchConfiguration, TextSubstitutionfrom launch_ros.actions import Node                    # 节点启动的描述类def generate_launch_description():                     # 自动生成launch文件的函数background_r_launch_arg = DeclareLaunchArgument('background_r', default_value=TextSubstitution(text='0')     # 创建一个Launch文件内参数(arg)background_r)background_g_launch_arg = DeclareLaunchArgument('background_g', default_value=TextSubstitution(text='84')    # 创建一个Launch文件内参数(arg)background_g)background_b_launch_arg = DeclareLaunchArgument('background_b', default_value=TextSubstitution(text='122')   # 创建一个Launch文件内参数(arg)background_b)return LaunchDescription([                                      # 返回launch文件的描述信息background_r_launch_arg,                                     # 调用以上创建的参数(arg)background_g_launch_arg,background_b_launch_arg,Node(                                                        # 配置一个节点的启动package='turtlesim',executable='turtlesim_node',                              # 节点所在的功能包name='sim',                                               # 对节点重新命名parameters=[{                                             # ROS参数列表'background_r': LaunchConfiguration('background_r'),   # 创建参数background_r'background_g': LaunchConfiguration('background_g'),   # 创建参数background_g'background_b': LaunchConfiguration('background_b'),   # 创建参数background_b}]),])

加载参数文件

import osfrom ament_index_python.packages import get_package_share_directory  # 查询功能包路径的方法from launch import LaunchDescription   # launch文件的描述类
from launch_ros.actions import Node    # 节点启动的描述类def generate_launch_description():     # 自动生成launch文件的函数config = os.path.join(              # 找到参数文件的完整路径get_package_share_directory('learning_launch'),'config','turtlesim.yaml')return LaunchDescription([          # 返回launch文件的描述信息Node(                            # 配置一个节点的启动package='turtlesim',          # 节点所在的功能包executable='turtlesim_node',  # 节点的可执行文件名namespace='turtlesim2',       # 节点所在的命名空间name='sim',                   # 对节点重新命名parameters=[config]           # 加载参数文件)])

在launch文件中使用条件变量

字段是condition,语法示例如下:

condition=IfCondition(variable)

IfCondition(variable)函数内只接受true, false, 0, 1参数,如果节点启动的描述中加入该字段并且参数值为false或0则节点不启动

完整的launch文件如下:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfConditiondef generate_launch_description():variable = LaunchConfiguration('start_flag', default='true')return LaunchDescription([DeclareLaunchArgument('start_flag',default_value=variable,description='This is the ros2_test_publisher_node start flag'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",condition=IfCondition(variable))])

此时

运行:ros2 launch ros2_test test.launch.py 节点会正常启动

运行:ros2 launch ros2_test test.launch.py start_flag:=false 节点不会启动

进阶的IfCondition函数使用方式:

由于LaunchConfiguration()函数的返回是一个对象,所以我们不可以拿来直接做运算,但是可以使用PythonExpression()做参数的表达式运算,语法如下:

PythonExpression([variable, '== 1']) 或
PythonExpression([variable, '+ 1 == 2']) 或
PythonExpression([variable, "== 'test'"]) 等等

完整的launch文件如下:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfConditiondef generate_launch_description():port_var = LaunchConfiguration('port', default='/dev/ttyS1')return LaunchDescription([DeclareLaunchArgument('port',default_value=port_var,description='This is the port address value'),Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output="screen",condition=IfCondition(PythonExpression([port_var, "== '/dev/ttyUSB0'"])))])

此时

运行:ros2 launch ros2_test test.launch.py 节点不会启动

运行:ros2 launch ros2_test test.launch.py port_var:=/dev/ttyUSB0 节点正常启动

action的分组

GroupAction():函数可以将一个或多个action加入到一个组中,组内可以共用参数,控制整组节点全部启动或全部不启动等,方便action的管理,需要接受的部分参数有:

  • actions:接受一个list, [action_1, action_2,…],列表中装要执行的action
  • condition:条件变量参数
  • launch_configuration:参数

PushRosNamespace()函数的作用是向test_group中设置组内的namespace,但是action_1中已经设置过了namespace,所以此时不会生效,该namespace只会在action_2中生效;

实例一:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import GroupAction
from launch_ros.actions import PushRosNamespacedef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen',namespace='my_ros2_test')action_2 = Node(package='ros2_test',executable='ros2_test_subscriber_node',name='ros2_test_subscriber_node',output='screen')test_group = GroupAction(actions=[PushRosNamespace("my_group_test"),action_1, action_2])return LaunchDescription([test_group])

action的启动延时控制

TimerAction():函数可以在指定的时间后执行一个action,需要接受参数有

  • period:接受一个float, 延迟的时间
  • actions:接受一个list, [action_1, action_2,…],列表中装要执行的action

实例一:

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import TimerActiondef generate_launch_description():action_1 = Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen')return LaunchDescription([TimerAction(period=5.0, actions=[action_1])])

Launch文件包含,在launch文件中调用另一个launch文件

PythonLaunchDescriptionSource() :在launch文件中调用其他launch需要调用函数,参数是被调用launch的路径。

实例一:

import osfrom ament_index_python.packages import get_package_share_directory  # 查询功能包路径的方法from launch import LaunchDescription                 # launch文件的描述类
from launch.actions import IncludeLaunchDescription  # 节点启动的描述类
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import GroupAction               # launch文件中的执行动作
from launch_ros.actions import PushRosNamespace      # ROS命名空间配置def generate_launch_description():                   # 自动生成launch文件的函数parameter_yaml = IncludeLaunchDescription(        # 包含指定路径下的另外一个launch文件PythonLaunchDescriptionSource([os.path.join(get_package_share_directory('learning_launch'), 'launch'),'/parameters_nonamespace.launch.py']))parameter_yaml_with_namespace = GroupAction(      # 对指定launch文件中启动的功能加上命名空间actions=[PushRosNamespace('turtlesim2'),parameter_yaml])return LaunchDescription([                        # 返回launch文件的描述信息parameter_yaml_with_namespace])

实例二:

import os
from ament_index_python import get_package_share_directory
from launch import LaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Nodedef generate_launch_description():return LaunchDescription([Node(package='ros2_test',executable='ros2_test_publisher_node',name='ros2_test_publisher_node',output='screen'),PythonLaunchDescriptionSource(os.path.join(get_package_share_directory('ros2_test'),'launch/test_subscriber.launch.py'))])

实例三:

from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import ThisLaunchFileDir
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration
from launch.actions import IncludeLaunchDescriptiondef generate_launch_description():inlucde_other_file = LaunchConfiguration('inlucde_other_file', default='true')test_var = LaunchConfiguration('test_var', default='test_var_2')return launch.LaunchDescription([IncludeLaunchDescription(PythonLaunchDescriptionSource([ThisLaunchFileDir(), '/test_subscriber.launch.py']),condition=IfCondition(inlucde_other_file),launch_arguments={'test_var': test_var}.items())])

在launch文件中运行脚本

ExecuteProcess():运行脚本同样可实现启动某个节点,同时该函数还支持condition、additional_env等参数的设置。

实例一:

from launch import LaunchDescription
from launch.actions import ExecuteProcessdef generate_launch_description():return LaunchDescription([ExecuteProcess(cmd=['ros2', 'run', 'ros2_test', 'ros2_test_publisher_node'],output="screen")])

在launch文件中设置环境变量或读取环境变量

SetEnvironmentVariable(var_name, var_value):函数用于设置环境变量,接受两个参数分别是要设置的环境变量名称和环境变量的值;

EnvironmentVariable(var_name):函数用于获取环境变量的值,返回值类型是一个对象,输入参数是要获取的环境变量名称;

完整launch文件实例:

from launch import LaunchDescription
from launch.actions import SetEnvironmentVariable, ExecuteProcess
from launch.substitutions import EnvironmentVariabledef generate_launch_description():return LaunchDescription([SetEnvironmentVariable('PRODUCT_MODEL', 'spray_robot'),ExecuteProcess(cmd=['echo', EnvironmentVariable('PRODUCT_MODEL')],output='screen')])

运行看到以下输出

[INFO] [echo-1]: process started with pid [195168]
[echo-1] spray_robot
[INFO] [echo-1]: process has finished cleanly [pid 195168]

launch 用法以及一些基础功能函数的示例

ros2 launch文件中最主要的概念是action,ros2 launch把每一个要执行的节点,文件,脚本,功能等全部抽象成action,用统一的接口来控制其启动,最主要的结构是:

def generate_launch_description():return LaunchDescription([action_1,action_2,...action_n])

要启动的节点或其他launch文件全部都传入LaunchDescription()函数中,该函数中接受一个或多launch.actionslaunch_ros.actions类型的对象,以下列举一下常用的action:

launch_ros.actions.Node· 此函数功能是启动一个ros2节点;
launch_ros.actions.PushRosNamespace· 此函数功能是给一个节点或组设置命名空间;
launch.actions.IncludeLaunchDescription· 此函数功能是直接引用另一个launch文件;
launch.actions.SetLaunchConfiguration· 此函数功能是在launch文件内声明一个参数,并给定参数值;
launch.actions.SetEnvironmentVariable· 此函数功能是声明一个环境变量并给定环境变量的值;
launch.actions.AppendEnvironmentVariable· 此函数将对一个环境变量追加一个值,如果不存在则创建;
launch.actions.DeclareLaunchArgument· 此函数功能是声明一个启动描述参数,该参数具有名称、默认值和文档;
launch.actions.TimerAction· 此函数功能是在一段时间后执行一个或多个action;
launch.actions.GroupAction· 此函数功能是将action分组,同组内的action可以统一设定参数方便集中管理;
launch.actions.ExecuteProcess· 此函数功能是根据输入执行一个进程或脚本;
launch.actions.EmitEvent· 此函数功能是发出一个事件,触发以注册的事件函数被调用;
launch.actions.RegisterEventHandler· 此函数功能是注册一个事件;
launch.actions.UnregisterEventHandler· 此函数功能是删除一个注册过的事件;

参数文件编译配置

功能包里面的参数文件,需要在setup.py里面做以下配置,编译的时候才能拷贝到include里面去

from setuptools import setup
import os
from glob import globpackage_name = 'learning_launch'setup(name=package_name,version='0.0.0',packages=[package_name],data_files=[('share/ament_index/resource_index/packages',['resource/' + package_name]),('share/' + package_name, ['package.xml']),(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*.launch.py'))),(os.path.join('share', package_name, 'config'), glob(os.path.join('config', '*.*'))),(os.path.join('share', package_name, 'rviz'), glob(os.path.join('rviz', '*.*'))),],install_requires=['setuptools'],zip_safe=True,maintainer='hcx',maintainer_email='huchunxu@guyuehome.com',description='TODO: Package description',license='TODO: License declaration',tests_require=['pytest'],entry_points={'console_scripts': [],},
)

这篇关于ros2 launch 用法以及一些基础功能函数的示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1025813

相关文章

#error用法

/* *检查编译此源文件的编译器是不是C++编译器 *如果使用的是C语言编译器则执行#error命令 *如果使用的是 C++ 编译器则跳过#error命令 */ #ifndef __cplusplus #error 亲,您当前使用的不是C++编译器噢! #endif #include <stdio.h> int main() {

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

Vim使用基础篇

本文内容大部分来自 vimtutor,自带的教程的总结。在终端输入vimtutor 即可进入教程。 先总结一下,然后再分别介绍正常模式,插入模式,和可视模式三种模式下的命令。 目录 看完以后的汇总 1.正常模式(Normal模式) 1.移动光标 2.删除 3.【:】输入符 4.撤销 5.替换 6.重复命令【. ; ,】 7.复制粘贴 8.缩进 2.插入模式 INSERT

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

ps基础入门

1.基础      1.1新建文件      1.2创建指定形状      1.4移动工具          1.41移动画布中的任意元素          1.42移动画布          1.43修改画布大小          1.44修改图像大小      1.5框选工具      1.6矩形工具      1.7图层          1.71图层颜色修改          1

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c