ubuntu20.04下安装qt5.12
https://blog.csdn.net/lj19990824/article/details/121013721
Ubuntu 20.04在桌面左侧边栏添加QT creator快捷图标
https://blog.csdn.net/kavieen/article/details/118695038
Qt和ROS:https://github.com/chengyangkj?tab=repositories
官方ROS2教程:https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html
catkin_make编译
https://blog.csdn.net/sinat_16643223/article/details/113935412
1.catkin_make编译流程
mkdir -p catkin_ws/src
将源码拷贝到 catkin_ws/src/目录下
cd catkin_ws/
catkin_make
2.启动ros服务端
第一个窗口运行:
roscore
第二个窗口运行:
cd catkin_ws/
source devel/setup.bash
rosrun arm_socket_connect arm_socket_connect_node
rosrun arm_socket_connect arm_connect_server
首先,您需要安装ROS2和C编译器。ROS2是一个机器人操作系统,它提供了一些工具和库,可以帮助您编写机器人应用程序。C是一种编程语言,它可以用来编写ROS2节点。
接下来,您需要创建一个ROS2工作区。这个工作区是一个文件夹,其中包含您的ROS2项目。您可以使用以下命令创建一个ROS2工作区:
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build
然后,您需要创建一个ROS2节点。节点是ROS2中的一个基本概念,它是一个可以与其他节点通信的进程。您可以使用以下命令创建一个ROS2节点:
cd ~/ros2_ws/src
ros2 pkg create my_node --build-type ament_cmake --node-name my_node
这将创建一个名为“my_node”的ROS2节点,并在“~/ros2_ws/src/my_node”文件夹中生成一些文件。
接下来,您需要在my_node.cpp
文件中编写节点代码。这个文件位于~/ros2_ws/src/my_node/src
文件夹中。您可以使用以下代码作为起点:
#include "rclcpp/rclcpp.hpp"
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("my_node");
RCLCPP_INFO(node->get_logger(), "Hello, world!");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
这个代码创建了一个名为“my_node”的ROS2节点,并在控制台输出“Hello, world!”。您可以根据需要修改这个代码,以实现您的节点功能。
最后,您需要编译和运行您的节点。您可以使用以下命令编译您的节点:
cd ~/ros2_ws
colcon build --packages-select my_node
这将编译您的节点,并将可执行文件放在“~/ros2_ws/install/my_node/bin”文件夹中。
要运行您的节点,请使用以下命令:
cd ~/ros2_ws
source install/setup.bash
ros2 run my_node my_node
这将启动您的节点,并在控制台输出“Hello, world!”。您可以根据需要修改这个命令,以实现您的节点功能。
以下是在ROS2中通过topic回调获取一帧图像信息的C++实现:
#include
#include
#include
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
class ImageSubscriber : public rclcpp::Node
{
public:
ImageSubscriber(const std::string & topic_name)
: Node("image_subscriber_node")
{
// Create a subscriber to the image topic
image_subscriber_ = create_subscription<sensor_msgs::msg::Image>(
topic_name, 10, std::bind(&ImageSubscriber::image_callback, this, std::placeholders::_1));
}
private:
void image_callback(const sensor_msgs::msg::Image::SharedPtr msg)
{
// Print the image width and height
std::cout << "Image width: " << msg->width << std::endl;
std::cout << "Image height: " << msg->height << std::endl;
// Convert the image data to OpenCV format
cv::Mat image = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)->image;
// Do some processing on the image
// ...
// Display the image
cv::imshow("Image", image);
cv::waitKey(1);
}
rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr image_subscriber_;
};
int main(int argc, char ** argv)
{
// Initialize the ROS2 node
rclcpp::init(argc, argv);
// Create an image subscriber
std::string topic_name = "/camera/image_raw";
auto image_subscriber = std::make_shared<ImageSubscriber>(topic_name);
// Spin the node
rclcpp::spin(image_subscriber);
// Shutdown the ROS2 node
rclcpp::shutdown();
return 0;
}
在上述代码中,我们创建了一个ImageSubscriber类,该类继承自rclcpp::Node类,用于订阅图像topic并处理接收到的图像数据。在ImageSubscriber类的构造函数中,我们创建了一个subscriber来订阅指定的图像topic,并将回调函数image_callback绑定到该subscriber上。在image_callback函数中,我们首先打印了接收到的图像的宽度和高度,然后将图像数据转换为OpenCV格式,并进行一些图像处理操作。最后,我们将处理后的图像显示出来。
在main函数中,我们首先初始化ROS2节点,然后创建一个ImageSubscriber对象来订阅指定的图像topic。最后,我们调用rclcpp::spin函数来启动ROS2节点,并等待接收到图像数据。当接收到图像数据时,ROS2会自动调用image_callback函数来处理数据。当我们想要停止节点时,可以调用rclcpp::shutdown函数来关闭ROS2节点。
功能:可以对多个ROS2节点分别进行进行启动和关闭,通过调用相关函数可启动或关闭某个指定节点,不会阻塞主线程,且不需要用户操作来退出某个节点。
以下是一个C++代码示例,可以对多个ROS2节点分别进行启动和关闭,通过调用相关函数可启动或关闭某个指定节点,不会阻塞主线程,且不需要用户操作来退出某个节点。
#include
#include
#include
#include
#include
#include
#include
class NodeManager
{
public:
NodeManager() {}
void add_node(std::shared_ptr<rclcpp::Node> node)
{
nodes_.push_back(node);
}
void start_all()
{
for (auto node : nodes_)
{
std::thread t(&NodeManager::start_node, this, node);
t.detach();
}
}
void stop_all()
{
for (auto node : nodes_)
{
std::thread t(&NodeManager::stop_node, this, node);
t.detach();
}
}
void start_node(std::shared_ptr<rclcpp::Node> node)
{
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this] { return !paused_; });
node->start();
}
void stop_node(std::shared_ptr<rclcpp::Node> node)
{
node->stop();
}
void pause_all()
{
std::unique_lock<std::mutex> lock(mutex_);
paused_ = true;
}
void resume_all()
{
std::unique_lock<std::mutex> lock(mutex_);
paused_ = false;
cv_.notify_all();
}
private:
std::vector<std::shared_ptr<rclcpp::Node>> nodes_;
std::mutex mutex_;
std::condition_variable cv_;
bool paused_ = false;
};
int main(int argc, char * argv[])
{
// 初始化ROS2节点
rclcpp::init(argc, argv);
// 创建节点管理器
NodeManager node_manager;
// 创建节点1
auto node1 = std::make_shared<rclcpp::Node>("node1");
node_manager.add_node(node1);
// 创建节点2
auto node2 = std::make_shared<rclcpp::Node>("node2");
node_manager.add_node(node2);
// 启动所有节点
node_manager.start_all();
// 暂停所有节点
node_manager.pause_all();
// 启动节点1
node_manager.resume_all();
// 等待一段时间
std::this_thread::sleep_for(std::chrono::seconds(5));
// 停止节点1
node_manager.stop_node(node1);
// 关闭ROS2节点
rclcpp::shutdown();
return 0;
}
在上面的代码中,我们使用了std::thread来启动和停止节点,这样可以避免阻塞主线程。在start_all函数和stop_all函数中,我们使用std::thread来启动和停止每个节点。我们使用t.detach()来分离线程,这样线程可以在后台运行,不会阻塞主线程。
在start_node函数中,我们使用了std::unique_lock和std::condition_variable来实现暂停和恢复节点的功能。当节点被暂停时,线程会等待条件变量cv_,直到被恢复时才会继续执行。
在main函数中,我们初始化ROS2节点,创建NodeManager对象,并向其添加两个节点。然后,我们启动所有节点,并暂停所有节点。接着,我们恢复节点1,并等待5秒钟。最后,我们停止节点1并关闭ROS2节点。
https://www.cnblogs.com/penuel/p/16396655.html
https://www.cnblogs.com/happyamyhope/p/12487096.html
解决方法:缺少头文件
#include "sensor_msgs/msg/image.hpp"
CMakeList.txt中增加sensor_msgs
库的依赖
find_package(sensor_msgs REQUIRED)
ament_target_dependencies(yourprojectname sensor_msgs)
解决方法:缺少头文件
#include
CMakeList.txt中增加sensor_msgs
库的依赖
find_package(cv_bridge REQUIRED)
ament_target_dependencies(yourprojectname cv_bridge)
解决方法:缺少头文件
#include
CMakeList.txt中增加sensor_msgs
库的依赖
find_package(image_transport REQUIRED)
ament_target_dependencies(yourprojectname image_transport)