ros2 basics #104 python c++ roslaunch cmake

2023-05-16

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 一.创建工作区
  • 二、加载模型
  • 三、正经地创建一个工作区的方法:
    • 1.c++
    • 2.编译
    • 3.launch.python
  • 4.c++编写ros2程序
  • 5.python编写ros2程序


一.创建工作区

ros2不像ros1那样需要catkin_init_workspace初始化工作空间,直接创建一个src文件夹,其中放入工程文件夹即可。
在这里插入图片描述
在这里插入图片描述
然后colcon build就可以编译了.

编译完后,导入setup.bash
然后ros2 launch turtlebot3_gazebo empty_world.launch.py
报错:
在这里插入图片描述
原因:未加入model模型

二、加载模型

GAZEBO_RESOURCE_PATH代表的是gazebo源,一般ubuntu系统安装了gazebo,就是指向系统的gazebo路径!不要再给一个路径!


//加入gazebo的模型文件
export GAZEBO_MODEL_PATH=/home/rz/test2/src/turtlebot3_simulations/turtlebot3_gazebo/models:${GAZEBO_MODEL_PATH}
//选择模型的类型。乌姆 嗯
export TURTLEBOT3_MODEL=waffle

之后再次roslaunch时候出现:
在这里插入图片描述
原因:在这里插入图片描述
在galactic版,有两个标签换名了(executable、name)
在这里插入图片描述
改为:
在这里插入图片描述
就可以用了。当然 不要忘记重新编译!!
成功!
在这里插入图片描述

三、正经地创建一个工作区的方法:

1.c++

ros2 pkg create <package_name> --build-type ament_cmake --dependencies <package_dependecies>

例:
在这里插入图片描述
查看工作pkg:
在这里插入图片描述

2.编译

1.colcon build:编译整个src工作区
2.colcon build --packages-select <package_name>:编译src中的package_name文件夹

3.launch.python

from launch import LaunchDescription
import launch_ros.actions


def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            package='', node_executable='', output=''),
    ])

在这里插入图片描述
这就是launch文件的大体格式:
package后是程序文件的父目录
node_executable后是程序文件在编译后,生成的可执行文件的名称!!!
output后是想要输出结果的方式,通常是"screen"

4.c++编写ros2程序

1.创建程序文件(cpp)

#include <chrono>
#include <functional>
#include <memory>
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"

using namespace std::chrono_literals;

/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */

class MinimalPublisher : public rclcpp::Node
{
  public:
    MinimalPublisher()
    : Node("minimal_publisher")
    {
      publisher_ = this->create_publisher<geometry_msgs::msg::Twist>("cmd_vel", 10);
      timer_ = this->create_wall_timer(
      500ms, std::bind(&MinimalPublisher::timer_callback, this));
    }

  private:
    void timer_callback()
    {
      auto message = std::make_shared<geometry_msgs::msg::Twist>();
      message->linear.x = 0.3;
      message->angular.z = 0.3;
      publisher_->publish(*message);
    }
    rclcpp::TimerBase::SharedPtr timer_;
    rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr publisher_;

  };

  int main(int argc, char * argv[])
  {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<MinimalPublisher>());
    rclcpp::shutdown();
    return 0;
  }

在这里插入图片描述
2.launch导入

from launch import LaunchDescription
import launch_ros.actions


def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            package='practice', executable='move_robot_node', output='screen'),
    ])                                     这里填写的'move_robot_node'是指生成后的名字   ,注意!此处的executabld前没有node!

3.修改cmakelists.txt 以 编译
在这里插入图片描述
这是自动生成的cmake文件
解释:
1.find_package:后面存放依赖项,这里我初始创建的时候,声明了ament_cmake(似乎是用于编译的默认文件)和rclcpp,在cpp程序中,还用到了geometry_msgs,因此需要添加:find_package(geometry_msgs REQUIRED)
在这里插入图片描述
2.add_executable:它会产生一个节点,第一个参数是节定名称,第二个参数用于存放可编译的程序文件,在编译的时候,就会把此文件转换为可执行文件因此还需要添加:add_executable(move_robot_node src/move_robot.cpp)

3.ament_target_dependencies:为执行文件添加依赖,这里需要添加:ament_target_dependencies(move_robot_node rclcpp geometry_msgs)

4.install(TARGETS 『可执行文件』 DESTINATION lib/ P R O J E C T N A M E ) : 这 里 指 的 是 下 载 必 要 文 件 到 i n s t a l l / l i b 文 件 夹 内 , 可 执 行 文 件 被 默 认 下 载 到   / r o s 2 w s / i n s t a l l / < p a c k a g e n a m e > / l i b . 因 此 需 要 添 加 : i n s t a l l ( T A R G E T S m o v e r o b o t n o d e D E S T I N A T I O N l i b / {PROJECT_NAME}):这里指的是下载必要文件到install/lib文件夹内,可执行文件被默认下载到~/ros2_ws/install/<package name>/lib.因此需要添加: install(TARGETS move_robot_node DESTINATION lib/ PROJECTNAME)install/lib /ros2ws/install/<packagename>/lib.install(TARGETSmoverobotnodeDESTINATIONlib/{PROJECT_NAME}
)
(这是默认要添加的东西!不要问为什么需要install)
这里的可执行文件就是上面add_executable中第一个参数(节点名)
5.install(DIRECTORY 『launch』 DESTINATION share/${PROJECT_NAME}/): 类似于上面,只不过下载的文件是launch。

添加完后,就可以编译了!
在这里插入图片描述
编译成功!
成功运行!小车开始转圈了。
在这里插入图片描述
ctrl+c,停止转圈的的节点后,小车依然旋转,是因为小车在依然接收最后一个旋转的主题,要想停止旋转,则发送一个停止转圈的主题即可!

ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}"

小车停止转圈。

5.python编写ros2程序

1.命令行创建python pkg

ros2 pkg create my_py_package --build-type ament_python --dependencies rclpy

在这里插入图片描述
package.xml: 关于包的元信息
setup.py:如何下载package的说明
setup.cfg:让ros2可以找到的程序路径,程序路径在编译时用到。
/package_name: 用于放自己编写的程序。

2.编写py程序

import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist


class MinimalPublisher(Node):

    def __init__(self):
        super().__init__('minimal_publisher')
        self.publisher_ = self.create_publisher(Twist, 'cmd_vel', 10)
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = Twist()
        msg.linear.x = 0.5
        msg.angular.z = 0.5
        self.publisher_.publish(msg)


def main(args=None):
    rclpy.init(args=args)

    minimal_publisher = MinimalPublisher()

    rclpy.spin(minimal_publisher)

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_publisher.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

放入my_py_package文件夹中。

3.编写launch文件

from launch import LaunchDescription
import launch_ros.actions


def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            package='my_py_package', executable='move_robot_node', output='screen'),
    ])

放入新建的launch文件夹内。

4.调整setup.py

from setuptools import setup
import os  //添加
from glob import glob    //添加

package_name = 'my_py_package'

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), glob('launch/*.launch.py')),//launch内所有的launch.py文件,将其下载至share文件夹内
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='rz',
    maintainer_email='rz@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
        	 'move_robot_node = my_py_package.move_robot:main',   //这句话意思:创建一个可执行文件,可执行文件名为move_robot_node,路径是在my_py_package.move_robot,指定main函数。
        ],
    },
)

import os //添加
from glob import glob //添加

data_files=[
(‘share/ament_index/resource_index/packages’,
[‘resource/’ + package_name]),
(‘share/’ + package_name, [‘package.xml’]),
(os.path.join(‘share’, package_name), glob(‘launch/*.launch.py’)),//launch内所有的launch.py文件,将其下载至share文件夹内
],

entry_points={
‘console_scripts’: [
‘move_robot_node = my_py_package.move_robot:main’, //这句话意思:创建一个可执行文件,可执行文件名为move_robot_node,路径是在my_py_package.move_robot,指定main函数。
],
},

5.调整setup.cfg
将程序内容变异后,下载的路径,就存在这里面!
在这里插入图片描述
检查依赖项目:

rosdep install -i --from-path src --rosdistro galactic -y

6.导入路径后,编译运行即可!
在这里插入图片描述
成功!小车再次转圈了

以上内容参考:
https://www.youtube.com/watch?v=ARIgQfu7ivE&list=PL4kY9sZGfkEFuSJC5vt-Y4iVVG7zWkWpR&index=57

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

ros2 basics #104 python c++ roslaunch cmake 的相关文章

随机推荐