ros2 basics #104 python c++ roslaunch cmake

ros2 basics #104 python c++ roslaunch cmake,第1张

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

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


一.创建工作区

ros2不像ros1那样需要class="superseo">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  --build-type ament_cmake --dependencies 

例:

查看工作pkg:

2.编译

1.colcon build:编译整个src工作区
2.colcon build --packages-select :编译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 
#include 
#include 
#include 

#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("cmd_vel", 10);
      timer_ = this->create_wall_timer(
      500ms, std::bind(&MinimalPublisher::timer_callback, this));
    }

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

  };

  int main(int argc, char * argv[])
  {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared());
    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 文 件 夹 内 , 可 执 行 文 件 被 默 认 下 载 到   / 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文件夹内,可执行文件被默认下载到~/ros2_ws/install//lib.因此需要添加: install(TARGETS move_robot_node DESTINATION lib/ PROJECTNAME)install /ros2ws/install/<packagename>/lib.install(TARGETSmoverobotnodeDESTINATIONlib/{PROJECT_NAME}
)
(这是默认要添加的东西!不要问为什么需要install)
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='[email protected]',
    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
将程序内容变异后,下载的路径,就存在这里面!

6.导入路径后,编译运行即可!

成功!小车再次转圈了

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/800970.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-07
下一篇 2022-05-07

发表评论

登录后才能评论

评论列表(0条)

保存