ROS系统基本功能的使用详解(基本指令/节点/服务/启动文件/动态参数)

2023-11-13

一、创建工作空间

1. 新建文件夹
新建一个catkin_ws的文件夹,并在里面创建src子目录。

mkdir -p ~/dev/catkin_ws/src
cd ~/dev/catkin_ws/src

2. 初始化工作空间
在刚创建的src子目录中,使用如下命令创建工作空间,但此时工作空间中还没有任何功能包,只有CMakeLists.txt。

catkin_init_workspace

3. 编译工作空间
回到工作空间的顶层目录catkin_ws文件夹中,使用catkin_make命令执行编译。编译完成后使用ll指令可以看到生成了builddevel两个文件夹。

cd ..
catkin_make

4. 完成配置
重新加载setup.bash文件,完成工作空间创建的最后一步配置

source devel/setup.bash

其实如果你在~/.bashrc中加入了此命令行,就可以通过重启终端得到同样的效果,添加命令如下,其中noetic是我的ros系统的版本号,如果你的版本不同,务必更改。

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc

二、创建与编译ROS功能包

1. 创建功能包
功能包可以通过手动方式创建,但为了方便,通常会使用catkin_create_pkg命令创建功能包,此命令的格式如下

catkin_create_pkg [package_name] [depend1] [depend2] [depend3]

其中的depend依赖项包括:

  • std_msgs:包含常见的消息类型,表示基本数据类型和其他基本的消息构造。
  • roscpp:使用C++编写ROS的各种功能。
例:
cd ~dev/catkin_ws/src
catkin_create_pkg test_package std_msgs roscpp

2. 编译功能包
回到catkin_ws文件夹下执行编译操作,如果没有报错,则说明功能包编译成功。

cd ..
catkin_make

三、ROS的基本命令

3.1 节点

1. rosnode指令
rosnode工具可以打印ROS节点的相关信息,具体命令如下:

rosnode指令 作用
rosnode ping NODE 测试节点的连通性
rosnode list 列出活动节点
rosnode info NODE 输出此节点的信息
rosnode machine 打印运行在特定计算机中的节点
rosnode kill NODE 结束节点进程
rosnode cleanup 将无法访问的节点的注册信息清除

2. 运行节点
首先使用roscore指令启动ros程序,然后再打开一个新的终端窗口执行接下来的操作。

我们可以使用rosrun指令运行一个节点

例:
rosrun turtlesim turtlesim_node

节点成功运行后再次使用rosnode list可以看到正在运行的节点,使用rosnode info /turtlesim可以查看此节点的详细信息,包括发布(Publications)、订阅(Subscriptions)以及节点具有的服务(Services)等。

3.2 主题

1. rostopic指令
节点可以通过发布主题和订阅主题实现数据的传输,通过主题的消息传输不需要节点直接连接,一个主题可以有多个订阅者和多个发布者。要实现主题与节点之间的交互,可以使用rostopic指令。

rostopic指令 作用
rostopic bw TOPIC 显示主题所用的带宽
rostopic echo TOPIC 将主题的消息输出到屏幕
rostopic find TOPIC 查找主题
rostopic hz TOPIC 显示主题发布频率
rostopic info TOPIC 输出主题详细信息
rostopic list TOPIC 列出活动主题
rostopic pubs TOPIC 将数据发布到主题
rostopic type TOPIC 输出主题的类型

2. 发布主题
可以通过rostopic list列出当前节点的主题。通过echo参数可以打印节点发出的消息,如:rostopic echo /turtle1/cmd_vel

此外,我们也可以直接通过rostopic pub发布主题,如下:

例:
rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '{linear: {x: 1, y: 0, z: 0}, angular: {x: 0, y: 0, z: 1}}'

3.3 服务

1. rosservice指令
服务是节点之间相互通信的另一种方法,服务允许节点发送请求和接受响应。可以使用rosservice指令操作服务。

  • roservice args /service:输出服务参数
  • rosservice call /service:根据命令行参数调用服务
  • rosservice find msgtype:根据服务类型查询服务
  • rosservice info /service:输出服务信息
  • rosservice list:列出活动服务清单
  • rosservice type /service:输出服务类型
  • rosservice uri /service:输出ROSRPC URI服务

2. 服务的使用
使用rosservice list可以列出所有的服务,使用rosservice call [service] [args]可以调用某个服务,例如rosservice call /clear可以清除海龟图上的线条。

此外,使用rossrv show turtlesim/Spawn可以查看/spawn服务的详细参数。

通过这些参数就可以调用/spawn服务创建第二只海龟。

rosservice call /spawn 3 3 0.5 "new_turtle"

3.4 参数服务器

1. rosparam指令
参数服务器存储了所有节点都可以访问的共享数据,可以通过rosparam指令管理参数服务器。

rosparam指令 作用
rosparam set parameter value 设置参数值
rosparam get parameter 获取参数值
rosparam load file 从文件加载参数
rosparam dump file 将参数保存至文件
rosparam delete parameter 删除参数
rosparam list 列出所有参数名

2. 使用参数服务器
以小海龟程序为例,通过rosparam list列出参数列表,可以看到背景background是turtlesim节点的参数,因此我们可以通过get指令获取参数值。

rosparam list
rosparam get /turtlesim/background_g
rosparam set /turtlesim/background_g 200

四、节点的创建与运行

这一部分会以一个具体实验为例,通过创建一个talker和一个listener并实现两者之间的信息交流,进而介绍创建节点的方法。

4.1 创建源文件

首先进入工作空间~/dev/catkin_ws文件夹中的功能包test_package/src/文件夹中,在这里创建两个cpp文件,分别作为消息的发送方和接收方。在这里我讲两个源文件分别命名talker.cpplistener.cpp

//talker.cpp
#include "ros/ros.h"	//包含ros节点的必要文件
#include "std_msgs/String.h"	//包含要使用的消息类型
#include <sstream>

int main(int argc, char **argv){
        ros::init(argc, argv, "talker");	//初始化节点并设置名称,所有ROS节点必须有这句
        ros::NodeHandle n;	//创建NodeHandle对象,用来与ROS系统通讯
        ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message", 1000);
        //创建一个主题发布者,并设置主题名称为message,缓冲区1000个消息
        ros::Rate loop_rate(10);	//数据发送频率10HZ
        while(ros::ok()){	//ctrl+c时返回0
                std_msgs::String msg;	//创建一个字符串的消息
                std::stringstream ss;	//定义一个字符串
                ss << "I'm talker node~~~";
                msg.data = ss.str();		//将字符串赋值给消息
                ROS_INFO("%s", msg.data.c_str());	//屏幕输出消息信息
                chatter_pub.publish(msg);	//发布消息
                ros::spinOnce();			//如果有订阅者出现,就会更新所有主题
                loop_rate.sleep();			//提供延时,保证10HZ的发布频率
        }
        return 0;
}


//listener.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"

//回调函数,节点每收到一条消息都会调用此函数
void messageCallback(const std_msgs::String::ConstPtr& msg){
        ROS_INFO("I am listener, I heard: [%s]",msg->data.c_str());
}

int main(int argc, char **argv){
        ros::init(argc, argv, "listener");
        ros::NodeHandle n;
        ros::Subscriber sub = n.subscribe("message", 1000, messageCallback);
        //创建一个订阅者,从message主题获取消息,设置缓冲区1000个消息,处理消息的回调函数为messageCallback
        ros::spin();	//消息回调处理,调用后不再返回
        return 0;
}

4.2 修改CMakeLists.txt

编辑catkin_ws/src/test_package/中的CMakeLists.txt,在最后加入如下的内容。

#include_directories(
        include
        ${catkin_INCLUDE_DIRS}
)

# 指定编译后可执行文件的名称
add_executable(talker src/talker.cpp)
add_executable(listener src/listener.cpp)
# 定义目标的依赖文件
add_dependencies(talker test_package_generate_messages_cpp)
add_dependencies(listener test_package_generate_messages_cpp)

target_link_libraries(talker ${catkin_LIBRARIES})
target_link_libraries(listener ${catkin_LIBRARIES})

4.3 编译节点

回到工作空间根目录进行编译:

cd ~/dev/catkin_ws
catkin_make

如果出现The dependency target does not exist.的错误,将CMakeLists.txt开头的cmake版本改为2.8.3即可。

编译完成后需要设置环境变量

echo "source ~/ros/tr3_6/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

4.4 运行节点

然后开始运行节点,首先运行roscore

roscore

然后再打开两个窗口分别运行

rosrun test_package example1_a
rosrun test_package example1_b

可以看到消息的接受和发送。
在这里插入图片描述

五、服务的创建与使用

本节将创建两个节点,分别作为服务器和客户端,通过服务的调用实现两个节点的数据传输,并实现数字求和的功能。

5.1 创建msg文件

使用服务之前,首先需要创建msg和srv文件,它们用于说明传输的数据类型和数据值。
1. 首先创建msg文件
test_package功能包下创建msg文件夹,并在msg文件夹中创建一个新的文件test_msg.msg。在文件中输入以下内容:

int32 num1
int32 num2
int32 num3

2. 编辑package.xml文件
package.xml文件中找到下面两行,取消这两行的注释<!-- -->

<!-- <build_depend>message_generation</build_depend> -->

<!-- <exec_depend>message_runtime</exec_depend> -->
<build_depend>message_generation</build_depend>

<exec_depend>message_runtime</exec_depend>

3. 编辑CMakeLists.txt文件
打开功能包目录下的CMakeLists.txt文件。

找到find_package(),在其中加入message_generation如下:

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  message_generation
)

找到如下的两段,取消注释,并将刚才创建的test_message.msg消息名称加入其中

## Generate messages in the 'msg' folder
add_message_files(
  FILES
  test_msg.msg
)
## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  std_msgs
)

4. 编译测试
进行完以上的步骤后,使用下面的命令进行编译:

cd ~/dev/catkin_ws/
catkin_make

编译完成后,要检查刚才创建的msg文件是否成功编译,使用rosmsg show指令:

rosmsg show test_package/test_msg

如果输出内容与test_msg.msg文件内的内容一致,说明编译正确。

5.2 创建srv文件

1. 创建srv文件
test_package功能包下创建srv文件夹,并在srv文件夹中创建一个新的文件test_srv.srv。在文件中输入以下内容:

int32 num1
int32 num2
int32 num3
---
int32 sum

2. 编辑package.xml文件
在创建msg文件时已经完成了package.xml文件的编辑,这里不需要额外的修改。

3. 编辑CMakeLists.txt
找到catkin_package,将其注释取消,并加入正确的数据如下:

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES test_package
#  CATKIN_DEPENDS roscpp std_msgs
#  DEPENDS system_lib
  CATKIN_DEPENDS message_runtime
)

取消add_service_files的注释,并添加刚创建的服务文件的名字。

## Generate services in the 'srv' folder
add_service_files(
  FILES
  test_srv.srv
)

4. 编译测试
完成上面的文件创建和修改后,使用下面的命令进行编译:

cd ~/dev/catkin_ws
catkin_make

编译完成后,要检测服务文件编译是否正确,可以使用rossrv show指令:

rossrv show test_package/test_srv.srv

如果打印内容与test_srv.srv文件内的内容一致,说明编译正确。

5.3 创建.cpp源文件

1. 创建源文件
在功能包文件夹中的src目录下catkin_ws/test_package/src,创建两个.cpp文件,分别为server.cppclient.cpp,分别作为服务器和客户端。


#include "ros/ros.h"
#include "test_package/test_srv.h"	//包含创建的srv文件

//对三个变量求和,并将计算结果发送给其他节点
bool add(test_package::test_srv::Request &req, test_package::test_srv::Response &res){
        res.sum = req.num1 + req.num2 + req.num3;
        ROS_INFO("request: num1=%ld, num2=%ld, num3=%ld", (int)req.num1, (int)req.num2, (int)req.num3);
        ROS_INFO("sending back response: [%ld]", (int)res.sum);
        return true;
}       

int main(int argc, char **argv){
        ros::init(argc, argv, "add_3_ints_server");
        ros::NodeHandle n;
        //创建服务"add_3_ints"的服务端,并在ROS中广播
        ros::ServiceServer service = n.advertiseService("add_3_ints", add);
        ROS_INFO("Ready to add 3 ints!");
        ros::spin();
        return 0;
} 
#include "ros/ros.h"
#include "test_package/test_srv.h"
#include <cstdlib>

int main(int argc, char **argv){
        ros::init(argc, argv, "add_3_ints_client");
        if(argc != 4){
                ROS_INFO("usage: add_3_ints_client num1 num2 num3");
                return 1;
        }

        ros::NodeHandle n;
        //以"add_3_ints"为名称创建客户端
        ros::ServiceClient client = n.serviceClient<test_package::test_srv>("add_3_ints");
        
        //创建srv文件的一个实例,并在其中加入需要发送的数据值
        test_package::test_srv srv;
        srv.request.num1 = atoll(argv[1]);
        srv.request.num2 = atoll(argv[2]);
        srv.request.num3 = atoll(argv[3]);
        
        //调用服务并发送数据,如果调用成功,服务端会返回true,否则返回false
        if(client.call(srv)){
                ROS_INFO("Sum: %ld", (long int)srv.response.sum);
        }
        else{
                ROS_ERROR("Failed to call service add_3_ints");
                return 1;
        }

        return 0;

} 

2. 编辑CMakeLists.txt

add_executable(server src/server.cpp)
add_executable(client src/client.cpp)

add_dependencies(server test_package_generate_messages_cpp)
add_dependencies(client test_package_generate_messages_cpp)

target_link_libraries(server ${catkin_LIBRARIES})
target_link_libraries(client ${catkin_LIBRARIES})

5.4 测试程序

回到catkin_ws工作空间中,进行编译。

cd ~/dev/catkin_ws
catkin_make

编译完成后,先打开一个终端,运行roscore,然后再打开两个新终端窗口,分别运行如下代码

rosrun test_package server
rosrun test_package client 6 4 2

可以看到服务端和客户端实现了消息的通信,完成了三个数字的求和计算。

在这里插入图片描述

六、启动文件的配置

在前面,我们已经实现了节点的创建和使用,但是每个节点都需要打开不同的命令行窗口执行,如果节点数目更多,那么启动节点将会是一件非常麻烦的事情。

通过启动文件我们可以在命令行窗口实现启动多个节点,只需要运行后缀名为.launch的文件即可启动多个节点。

6.1 创建.launch文件

首先在功能包内创建一个名为launch的文件夹,并在其中创建test.launch文件。

roscd test_package
mkdir launch
cd launch
vim test.launch

test.launch文件内输入如下内容:

<?xml version="1.0"?>
<launch>
	<node name="talker" pkg="test_package" type="talker" />
	<node name="listener" pkg="test_package" type="listener" />
</launch>

6.2 启动节点

上面编写的启动文件可以启动前文实验的talkerlistener两个节点,启动命令如下:

roslaunch test_package test.launch

系统会输出以下信息,说明启动成功。
在这里插入图片描述
使用rosnode list可以列出活动的节点,可以看到我们已经成功启动了talkerlistener两个节点。
在这里插入图片描述
如果想看到两个节点传递的信息,可以使用rqt_console
在这里插入图片描述

七、动态参数的使用

一般情况下,我们编写一个节点时,只能以数据初始化节点内的变量,如果我们想要改变这些变量值,可以使用主题,服务或参数服务器,但这种方式无法在线动态更新,如果listener不主动查询,我们无法知道参数是否更新。有时我们需要在线动态更新参数,这时就需要使用动态参数。

7.1 创建配置文件

首先在功能包内新建一个名为cfg的文件夹,并在其内创建一个test.cfg文件。

roscd test_package
mkdir cfg
cd cfg
vim test.cfg

test.cfg内添加如下代码:

# 初始化ROS并导入参数生成器
#!/usr/bin/env python
PACKAGE = "test_package"
from dynamic_reconfigure.parameter_generator_catkin import *

# 初始化参数生成器,通过gen我们可以添加参数
gen = ParameterGenerator()

# 加入不同的参数类型并设置默认值、描述、取值范围等
# gen.add(name, type, level, description, default, min, max)
gen.add("double_param", double_t, 0, "A double parameter", .1, 0, 1)
gen.add("str_param", str_t, 0, "A string parameter", "test_default_string")
gen.add("int_param", int_t, 0, "An Integer parameter", 1, 0, 100)
gen.add("bool_param", bool_t, 0, "A Boolean parameter", True)

size_enum = gen.enum([gen.const("Low", int_t, 0, "Low is 0"), gen.const("Medium", int_t, 1, "Medium is 1"), gen.const("High", int_t, 2, "High is 2"), gen.const("Exlarge", int_t, 3, "Exlarge is 3")], "Select from the list")

gen.add("size", int_t, 0, "Select from the list", 1, 0, 3, edit_method=size_enum)

# 生成必要的文件并退出程序
exit(gen.generate(PACKAGE, "test_package", "test_"))



由于test.cfg是由ROS执行的可执行文件,因此我们需要改变文件权限:

chmod a+x test.cfg

7.2 修改CMakeLists.txt添加配置文件的编译

打开CMakeLists.txt,找到find_package,在最后加入dynamic_reconfigure如下:

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  message_generation
  dynamic_reconfigure
)

找到generate_dynamic_reconfigure_options,取消注释,并将内部的配置文件改为刚创建的配置文件。

## Generate dynamic reconfigure parameters in the 'cfg' folder
generate_dynamic_reconfigure_options(
  cfg/test.cfg
)

7.3 创建节点

接下来需要创建一个具有动态配置支持的新节点。

src文件夹下创建一个新文件如下:

roscd test_package
vim src/dynamic_param.cpp

在文件中写入如下代码:

#include <ros/ros.h>
#include <dynamic_reconfigure/server.h>
#include <test_package/test_Config.h>

//回调函数将输出参数的新值,参数名称必须与test.cfg配置文件相同
void callback(test_package::test_Config &config, uint32_t level){
        ROS_INFO("Reconfigure Request: %d %f %s %s %d", config.int_param, config.double_param, config.str_param.c_str(), config.bool_param?"True":"False", config.size);
}

int main(int argc, char **argv){
        ros::init(argc, argv, "test_dynamic_reconfigure");
        //初始化服务器
        dynamic_reconfigure::Server<test_package::test_Config> server;
		//向服务器发送回调函数,当服务器得到重新配置请求,会调用回调函数        
        dynamic_reconfigure::Server<test_package::test_Config>::CallbackType f;
        f = boost::bind(&callback, _1, _2);
        server.setCallback(f);

        ros::spin();
        return 0;
}   

7.4 修改CMakeLists.txt添加节点的编译

add_executable(dynamic_param src/dynamic_param.cpp)
add_dependencies(dynamic_param test_package_gencfg)
target_link_libraries(dynamic_param ${catkin_LIBRARIES})

7.5 运行配置

打开三个终端命令行窗口,分别运行如下的命令:

roscore
rosrun test_package dynamic_param
rosrun rqt_reconfigure rqt_reconfigure

执行完成后,会看到一个rqt_reconfigure窗口,在这个窗口中就可以动态的配置节点的参数,并且在调整参数时,可以看到命令行打印参数的改变。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS系统基本功能的使用详解(基本指令/节点/服务/启动文件/动态参数) 的相关文章

  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 在 C# 中按元素相乘数组具有意想不到的性能

    我想找到按元素相乘两个数组的最佳方法 这是更广泛项目的一部分 其中性能而不是唯一的考虑因素 我今天开始用 C Linqpad 编写一些函数 因此它还没有以任何方式进行优化 下面代码的输出如下 Environment ProcessorCou
  • 使用 Enumerable.OfType() 或 LINQ 查找特定类型的所有子控件

    Existed MyControl1 Controls OfType
  • 读取 C# 中的默认应用程序设置

    我的自定义网格控件有许多应用程序设置 在用户范围内 其中大部分是颜色设置 我有一个表单 用户可以在其中自定义这些颜色 并且我想添加一个用于恢复默认颜色设置的按钮 如何读取默认设置 例如 我有一个名为的用户设置CellBackgroundCo
  • 为什么这个没有特殊字符的正则表达式会匹配更长的字符串?

    我正在使用此方法来尝试查找匹配项 例如 Regex Match A2 TS OIL TS OIL RegexOptions IgnoreCase Success 我得到了真实的结果 我很困惑 我认为这应该返回 false 因为模式中没有特殊
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • Ubuntu 12.04 上的 DeepDive 安装指南

    在拥有以后很多问题 https stackoverflow com questions 22469188 deepdive installation postgresql error安装深潜项目 http deepdive stanford
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 更改 Windows Phone 系统托盘颜色

    有没有办法将 Windows Phone 上的系统托盘颜色从黑色更改为白色 我的应用程序有白色背景 所以我希望系统托盘也是白色的 您可以在页面 XAML 中执行此操作
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • vue 省市区三级联动选择 pc端项目插件element-china-area-data(非常推荐)

    使用步骤 1 npm install element china area data S 2 import provinceAndCityData regionData provinceAndCityDataPlus regionDataP
  • 解决挂载ext4格式文件系统错误 JBD2: Unrecognised features on journal问题

    1 mount demo img mnt dmesg 报如下错误 1479130 280508 JBD2 Unrecognised features on journal 1479130 280512 EXT4 fs loop1 error
  • python 如果你的年龄大于18_python基础

    在python是空格是很重要的比如 如果在print前面加一个空格就会报错 在python中你必须顶格写 if 要判断的条件 条件成立时要执行的事情 图1 在图1中要判断的条件是年龄是不是大于18岁 大于18岁就可以去酒吧了 else语句配
  • Qt实现简单的显示网页(QtWebkit、QtWebEngine、QAxWidget)

    首先先说说QtWebkit QtWebEngine QAxWidget三种方式显示网页的应用场景 QtWebkit 在Qt5 6以前 都是使用QtWebkit组件 但Qt5 6以后 移除了QtWebkit这个组件 QtWebEngine Q
  • 握手信号valid/ready的打拍技巧

    一 前言 valid和ready信号 尤其是ready信号的时序一般很差 因为它通常是接收端通过组合逻辑输出的 当流水线的级数较多时 ready反压信号一级一级往前传递 时序将会变得更差 为了优化时序 通常需要对valid和ready信号进
  • Pyhton,OpenCV对象检测之——Haar级联人脸及眼睛检测

    Pyhton OpenCV对象检测之 Haar级联人脸及眼睛检测 1 效果图 2 原理 2 1 Haar人脸检测原理 2 2 Haar级联预训练的模型 3 源码 3 1 图像面部及眼睛检测 3 2 视频帧面部及眼睛检测 参考 这篇博客将介绍
  • CMD找不到Python?

    前言 当我们费完一牛一虎之力给我们的Windows装上python后 却发现在CMD中输入python时发生这样一幕 D gt python python 不是内部或外部命令 也不是可运行的程序或批处理文件 那么这就需要来Look一下这篇文
  • shell中条件判断单双中括号&数值比较&字符串比较

    文章目录 条件判断中的单双中括号 单中括号 双中括号 背景 在修改centreon监控脚本的时候发现shell脚本中if判断条件使用的几点疑问 遂记录 条件判断中的单双中括号 样例1如下 判断当前小时 24小时制 是否大于2点 time d
  • [Interview系列 知识储备回顾] 集合篇 - Map[1]

    concurrentHashMap考点分析 concurrentHashMap在JDK 1 7怎么解决线程安全 concurrentHashMap在JDK 1 8怎么解决线程安全 concurrentHashMap在JDK 1 7怎么解决线
  • JeeSite数据权限控制解决方案

    支持如下数据范围设置 所有数据 所在公司及以下数据 所在公司数据 所在部门及以下数据 所在部门数据 仅本人数据 按明细设置 特殊情况下 跨机构授权 User user UserUtils getUser 使用标准查询 DetachedCri
  • 【python设置临时环境变量】export PYTHONPATH=$(pwd):${PYTHONPATH}

    PYTHONPATH是Python搜索路径 默认我们import的模块都会从PYTHONPATH里面寻找 打印PYTHONPATH import os print sys path gt usr local lib python2 7 di
  • 机器学习之朴素贝叶斯

    朴素贝叶斯 贝叶斯法则 条件独立 如果P X Y Z P X Z P Y Z 或等价地P X Y Z P X Z 则称事件X Y对于给定事件Z是条件独立的 也就是说 当Z发生时 X发生与否与Y发生与否是无关的 朴素贝叶斯 假设每个输入变量独
  • Qt + OpenGL 教程(六):旋转的几种方法(自动旋转、键盘控制、鼠标控制旋转)

    总结了几种旋转的方法 自动旋转 利用计时器 每隔一段时间重新绘制屏幕 实现旋转 键盘控制 点击某个按键 旋转某一角度 鼠标控制 围绕y轴 跟随鼠标旋转 目前只是围绕y轴旋转 不能按任意轴旋转 代码分别为 以后补充
  • ORB_SLAM2 源码解析 特征匹配 (五)

    目录 一 单目初始化中的特征匹配SearchForInitialization 二 跟踪 TrackwithModel TrackReferenceKeyFrame 三 词袋介绍BoW 1 直观理解词袋 2 词袋基本思想 3 从字典结构到k
  • 使用D3.js实现框选节点并进行多节点拖动

    最近再使用d3 js关系图形展示时 需要选中多节点并进行拖动 一开始并不知道D3提供了此API 下面是我结合项目业务整理的框选操作的重点方面的应用 这是d3提供的api 使用鼠标或触摸选择一维或二维区域 可参考示例 https blockb
  • Unity 使用 Dotween 的 Sequence 制作UI动画并且可重复利用

    目录 前言 一 DOTween是什么 二 使用步骤 1 导入DOTween 2 配置DOTween 3 使用代码编写动画 4 代码API解释 总结 前言 DOTween可以制作简易的UI动画 避免创建大量的Animator 本篇文章介绍一下
  • Spring Boot + k8s 最佳实践

    前言 K8s Spring Boot实现零宕机发布 健康检查 滚动更新 优雅停机 弹性伸缩 Prometheus监控 配置分离 镜像复用 配置 健康检查 健康检查类型 就绪探针 readiness 存活探针 liveness 探针类型 ex
  • 书店管理系统

    设计一个书店管理系统 能完成书店的日常管理工作 要求完成的基本功能 1 进货入库记录 2 销售出货记录 3 图书信息查询 可通过书名 作者等途径查询某本图书的详细信息 含书名 作者 出版社 页数 最新入库时间 库存量 价格等 4 自动预警提
  • 时间和日期

    Boost使用的timer和data timerj进行对应和时间日期相关的出来文档 timer包含三个组件 分别为timer progress timer以及对应的progress display timer timer可以测量运行时间 t
  • ROS系统基本功能的使用详解(基本指令/节点/服务/启动文件/动态参数)

    ROS系统基本功能的使用详解 一 创建工作空间 二 创建与编译ROS功能包 三 ROS的基本命令 3 1 节点 3 2 主题 3 3 服务 3 4 参数服务器 四 节点的创建与运行 4 1 创建源文件 4 2 修改CMakeLists tx