创建package和查看package的依赖关系

本文介绍了如何使用roscreate命令创建ROS包,包括目录结构、依赖包管理及配置方法。

Creating a ROS Package



目录

Using roscreate

Before we create a package, let's see how the roscreate-pkg command-line tool works. This creates a new ROS package. All ROS packages consist of the many similar files : manifests, CMakeLists.txt, mainpage.dox, and Makefiles. roscreate-pkg eliminates many tedious tasks of creating a new package by hand, and eliminates common errors caused by hand-typing build files and manifests.

To create a new package in the current directory:

$ roscreate-pkg [package_name]

You can also specify dependencies of that package:

$ roscreate-pkg [package_name] [depend1] [depend2] [depend3]

Creating a New ROS Package

Now we're going to go into your home or project directory and create our beginner_tutorials package. We are going to make it depend on std_msgs, roscpp, and rospy, which are common ROS packages.

Now go into the ~/fuerte_workspace/sandbox directory:

$ cd ~/fuerte_workspace/sandbox

Alternatively, if you use Fuerte or later release, you can simply do:

$ roscd

Then create your package:

$ roscreate-pkg beginner_tutorials std_msgs rospy roscpp

You will see something similar to:

  • Creating package directory ~/fuerte_workspace/sandbox/beginner_tutorials
    Creating include directory ~/fuerte_workspace/sandbox/beginner_tutorials/include/beginner_tutorials
    Creating cpp source directory ~/ros/ros_tutorials/beginner_tutorials/src
    Creating python source directory ~/fuerte_workspace/sandbox/beginner_tutorials/src/beginner_tutorials
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/Makefile
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/manifest.xml
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/CMakeLists.txt
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/mainpage.dox
    
    Please edit beginner_tutorials/manifest.xml and mainpage.dox to finish creating your package

You're going to want to spend some time looking at beginner_tutorials/manifest.xml. manifests play an important role in ROS as they define how Packages are built, run, and documented.

Now lets make sure that ROS can find your new package. It is often useful to call rospack profile after making changes to your path so that new directories will be found:

$ rospack profile
$ rospack find beginner_tutorials 
  • YOUR_PACKAGE_PATH/beginner_tutorials

If this fails, it means ROS can't find your new package, which may be an issue with your ROS_PACKAGE_PATH. Please consult the installation instructions for setup from SVN or from binaries, depending how you installed ROS. If you've created or added a package that's outside of the existing package paths, you will need to amend your ROS_PACKAGE_PATH environment variable to include that new location. Try re-sourcing your setup.sh in your fuerte_workspace.

Try moving to the directory for the package.

$ roscd beginner_tutorials 
$ pwd
  • YOUR_PACKAGE_PATH/beginner_tutorials

First-order package dependencies

When using roscreate-pkg earlier, a few package dependencies were provided. These first-order dependencies can now be reviewed with the rospack tool.

$ rospack depends1 beginner_tutorials 
  • std_msgs
    rospy
    roscpp

As you can see, rospack lists the same dependencies that were used as arguments when running roscreate-pkg. These dependencies for a package are stored in the manifest file. Take a look at the manifest file.

$ roscd beginner_tutorials
$ cat manifest.xml
  • <package>
    
    ...
    
      <depend package="std_msgs"/>
      <depend package="rospy"/>
      <depend package="roscpp"/>
    
    </package>

Indirect package dependencies

In many cases, a dependency will also have its own dependencies. For instance, rospy has other dependencies.

$ rospack depends1 rospy
  • roslib
    roslang

A package can have quite a few indirect dependencies. Luckily rospack can recursively determine all nested dependencies.

$ rospack depends beginner_tutorials
  • rospack
    roslib
    std_msgs
    rosgraph_msgs
    rosbuild
    roslang
    rospy
    cpp_common
    roscpp_traits
    rostime
    roscpp_serialization
    xmlrpcpp
    rosconsole
    roscpp

Note: in Fuerte, the list is much shorter:

std_msgs
roslang
rospy
roscpp

在 Oracle 数据库中,`PACKAGE` `PACKAGE BODY` 是 PL/SQL 中用于组织封装相关过程、函数、变量、游标等的数据库对象。它们分为两个部分: - **Package Specification(包规范)**:定义接口(声明),包括可被外部调用的过程函数原型。 - **Package Body(包体)**:实现这些过程函数的具体逻辑,并可包含私有成员(仅包内可见)。 --- ### ✅ 创建 PACKAGE PACKAGE BODY 的步骤 #### 1. **创建 Package Specification(包规范)** ```sql CREATE OR REPLACE PACKAGE emp_package AS -- 声明一个函数:根据员工编号返回工资 FUNCTION get_salary(emp_id NUMBER) RETURN NUMBER; -- 声明一个过程:给指定员工加薪 PROCEDURE raise_salary(emp_id NUMBER, amount NUMBER); -- 声明一个公共变量 g_dept_name VARCHAR2(50); -- 声明一个游标 CURSOR c_employees RETURN employees%ROWTYPE; END emp_package; / ``` > 🔹 使用 `CREATE OR REPLACE PACKAGE` 可以创建新包或替换已有包。 > 🔹 所有在规范中声明的对象都是“公有”的,可以在包外访问。 --- #### 2. **创建 Package Body(包体)** ```sql CREATE OR REPLACE PACKAGE BODY emp_package AS -- 私有变量(只能在包内部使用) v_last_updated DATE; -- 实现函数 FUNCTION get_salary(emp_id NUMBER) RETURN NUMBER IS v_salary NUMBER; BEGIN SELECT salary INTO v_salary FROM employees WHERE employee_id = emp_id; RETURN v_salary; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NULL; END get_salary; -- 实现过程 PROCEDURE raise_salary(emp_id NUMBER, amount NUMBER) IS BEGIN UPDATE employees SET salary = salary + amount WHERE employee_id = emp_id; -- 更新时间戳 v_last_updated := SYSDATE; END raise_salary; -- 定义游标 CURSOR c_employees RETURN employees%ROWTYPE IS SELECT * FROM employees; -- 包初始化代码块(可选) BEGIN v_last_updated := SYSDATE; g_dept_name := 'HR Department'; END emp_package; / ``` > 🔹 包体必须与包规范中的声明一一对应(除非是私有元素)。 > 🔹 可以在包体内定义**私有变量、过程、函数**,不会暴露给外部。 > 🔹 `BEGIN ... END;` 后面的初始化块会在第一次引用包时执行一次。 --- ### 📌 示例说明 假设你的表结构如下: ```sql -- 示例 employees 表 CREATE TABLE employees ( employee_id NUMBER PRIMARY KEY, name VARCHAR2(100), salary NUMBER, department VARCHAR2(50) ); ``` 插入测试数据: ```sql INSERT INTO employees VALUES (1, 'Alice', 5000, 'HR'); INSERT INTO employees VALUES (2, 'Bob', 6000, 'IT'); COMMIT; ``` 现在可以调用包中的内容: ```sql -- 调用函数 SELECT emp_package.get_salary(1) FROM dual; -- 调用过程 BEGIN emp_package.raise_salary(1, 500); COMMIT; END; / -- 查看结果 SELECT * FROM employees; ``` --- ### 🧩 优点总结 | 特性 | 说明 | |------|------| | **模块化** | 将相关逻辑组织在一起 | | **信息隐藏** | 私有成员不可见,增强安全性 | | **性能提升** | 包变量可在会话期间保持状态 | | **易于维护** | 接口与实现分离 | --- ### 💡 注意事项 - 必须先创建或存在 **Package Specification**,才能创建其 **Body**。 - 修改包规范后,所有依赖它的程序可能需要重新编译。 - 可通过 `USER_OBJECTS` 观察包的状态: ```sql SELECT object_name, object_type, status FROM user_objects WHERE object_name = 'EMP_PACKAGE'; ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值