Note: This tutorial assumes that you have completed the previous tutorials: navigating the ROS filesystem. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
إنشاء حزمة ROS
Description: يشمل هذا الدرس roscreate-pkg و catkin لإنشاء حزمة جديدة، و rospack لعرض قائمة بأسماء المكتبات التي تعتمد عليها الحزمة.Tutorial Level: BEGINNER
Next Tutorial: Building a ROS package
Contents
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 $ cd sandbox
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.
(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy; it may take some time to be reflected in the packages. If you see an issue similar to this with the next command, you can skip to the following command.
$ 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.
(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy; it may take some time to be reflected in the packages. If you see an issue similar to this with the next command, you can skip to the following command.
$ 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
ROS Client Libraries
You may be wondering what rospy and roscpp dependencies are from the previous examples. rospy and roscpp are Client Libraries. The client libraries allow different programming languages to communicate through ROS. rospy is the client library for Python. roscpp is the client library for C++.
Review
Lets just list some of the commands we've used so far:
- roscreate-pkg = ros+create-pkg : generates all the files needed to create a ROS package
- rospack = ros+pack(age) : provides information related to ROS packages
- rosstack = ros+stack : provides information related to ROS stacks
ما هي مكونات حزمة catkin؟
كي تعتبر حزمة ما حزمة catkin يجب أن تحقق المتطلبات التالية:
يجب أن تحتوي الحزمة على ملف توصيف catkin compliant package.xml.
- يجب أن يحتوي ملف التوصيف package.xml على معلومات أولية عن الحزمة.
يجب أن تحتوي الحزمة ملف بناء CMakeLists.txt which uses catkin.
إن كانت الحزمة وسيطية catkin metapackage فيجب أن تحتوي ملف بناء CMakeLists.txt مناسب.
- كل حزمة يجب أن تحتوى في مجلد خاص بها.
- أي لا يسمح باشتراك الحزم في مجلد واحد، ولا يسمح بوجود حزمة داخل حزمة.
أبسط شكل للحزمة يبدو على الشكل التالي:
my_package/ CMakeLists.txt package.xml
الحُزَم في فضاء عمل catkin
الطريقة المفضلة للتعامل مع حزم catkin هي استخدام فضاء عمل catkin، لكن يمكن بناء حزم catkin بشكل مستقل. فضاء العمل في أبسط أشكاله يبدو كما يلي:
workspace_folder/ -- WORKSPACE src/ -- SOURCE SPACE CMakeLists.txt -- 'Toplevel' CMake file, provided by catkin package_1/ CMakeLists.txt -- CMakeLists.txt file for package_1 package.xml -- Package manifest for package_1 ... package_n/ CMakeLists.txt -- CMakeLists.txt file for package_n package.xml -- Package manifest for package_n
قبل متابعة هذا الدرس، أنشأ مجلداً فارغاً (كما في الدرس السابق إنشاء فضل عمل catkin).
إنشاء حزمة catkin
تبين الفقرات التالية كيفية استخدام الملف catkin_create_pkg لإنشاء حزمة جديدة، وماذا يمكن أن تفعل بالحزمة بعد ذلك.
أولاً غير مسار موجه الأوامر إلى مجلد الرمازا المصدري (src) الذي أنشأته في الدرس السابق إنشاء فضاء عمل catkin
# You should have created this in the Creating a Workspace Tutorial
$ cd ~/catkin_ws/src
الآن استخدم التعليمة catkin_create_pkg لإنشاء حزمة اسمها 'beginner_tutorials' تعتمد على المكتبات std_msg، roscpp، rospy:
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
تنشئ هذه التعليمة مجلداً beginner_tutorials يحتوي على ملفي التوصيف package.xml والبناء CMakeLists.txt. واللذان تم ملؤهما بمعلومات مناسبة لاسم الحزمة والمكتبات المعتمدة عليها، وتعليمات مناسبة للبناء، وأخرى عن صاحب الحزمة.
تتطلب التعلمية catkin_create_pkg اسم الحزمة package_name واختيارياً أسماء المكتبات التي تعتمد الحزمة عليها، أي لها القالب التالي (لا تحاول تنفيذه):
# This is an example, do not try to run this # catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
تؤمن catkin_create_pkg وظائف متقدمة أكثر، موصفة في الرابط catkin/commands/catkin_create_pkg.
بناء فضاء عمل catkin، والتصريح عن ملف الإعداد
ابنِ الحزم في فضاء عمل catkin باستخدام التعليمة:
$ cd ~/catkin_ws
$ catkin_make
عندما تنتهي عملية البناء، نكون قد حصلنا على مجلد بناء build ومجلد تطوير devel داخل مجلد فضاء العمل (شبيه بمجلد التطوير في المسار /opt/ros/$ROSDISTRO_NAME).
لإضافة فضاء العمل إلى بيئة ROS يجب التصريح عن ملف الإعداد المنشأ تلقائياً في مجلد التطوير:
$ . ~/catkin_ws/devel/setup.bash
مُعتَمَدات الحزمة
=== معتمدات المرتبة الأولى ==
عند استخدام catkin_create_pkg، تُؤمَّن بشكل تلقائي عدة مكتبات. تعتبر هذه المكتبات كمعتمدات من المرتبة الأولى. يمكن عرضها باستخدام أدوات rospack.
$ rospack depends1 beginner_tutorials
roscpp rospy std_msgs
كما ترى فإن القائمة المعروضة تحتوي العمتمدات نفسها التي ذكرناها عند إنشاء الحزمة باستخدام catkin_create_pkg. هذه المعتمدات مخزنة داخل ملف التوصيف package.xml:
$ roscd beginner_tutorials $ cat package.xml
<package format="2"> ... <buildtool_depend>catkin</buildtool_depend> <build_depend>roscpp</build_depend> <build_depend>rospy</build_depend> <build_depend>std_msgs</build_depend> ... </package>
المُعتمَدات غير المُباشَرة
في كثير من الأحيان يكون للمكتبة المعتمد عليها مكتبات أخرى تعتمد هي عليها. مثلاً rospy لها معتمداتها:
$ rospack depends1 rospy
genpy roscpp rosgraph rosgraph_msgs roslib std_msgs
كما يمكن للحزمة أن تمتلك معتمدات غير مباشرة. تسمح rospack وبشكل عودي recursively بتحديد المكتبات المعتمد عليها بشكلٍ متتالٍ nested.
$ rospack depends beginner_tutorials
cpp_common rostime roscpp_traits roscpp_serialization catkin genmsg genpy message_runtime gencpp geneus gennodejs genlisp message_generation rosbuild rosconsole std_msgs rosgraph_msgs xmlrpcpp roscpp rosgraph ros_environment rospack roslib rospy
تخصيص حزمتك
هذا الجزء من الدرس سينظر إلى الملفات المولدة باستخدام catkin_create_pkg وتوصيفها سطراً بسطر، وكل مكون من هذه الملفات وكيفية تخصيصه.
تخصيص ملف التوصيف package.xml
ملف التوصيف المولد package.xml يجب أن يكون في داخل مجلد الحزمة. لنبحث في داخل هذا الملف ومكوناته.
علامة التوصيف
أولاً حدث علامة التوصيف description tag:
5 <description>The beginner_tutorials package</description>
غير التوصيف لأي شيء تريده، بجملة مختزلة، يفضل أن تكون قصيرة ومعبرة عن وظيفة الحزمة. في حال استحالة ذلك يمكن تقسيم الجملة إلى عدة جمل.
علامات المشرفين
ثم تأتي علامة المشرف maintainer tag:
7 <!-- One maintainer tag required, multiple allowed, one person per tag -->
8 <!-- Example: -->
9 <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
10 <maintainer email="user@todo.todo">user</maintainer>
تعتبر هذه العلامة ضرورية ومهمة للحزمة package.xml لأنها تخبر المستخدمين الآخرين عن كيفية التواصل مع صاحب الحزمة. يجب إضافة مشرف واحد على الأقل، ويمكن إضافة أكثر من مشرف. اسم المشرف يكتب في عرض العلامة، أما بريده الإلكتروني فله علامة خاصة.
7 <maintainer email="you@yourdomain.tld">Your Name</maintainer>
علامات الترخيص
تعتبر علامة الترخيص license مهمة
12 <!-- One license tag required, multiple allowed, one license per tag -->
13 <!-- Commonly used license strings: -->
14 <!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
15 <license>TODO</license>
يسمح الترخيص بمعرفة ماذا يمكن أن يفعل المطور الآخر بهذه الحزمة، مثلاً يمكن أن يستخدمها لأغراض تطويرية وليس تجارية ، أو كليهما أو غير ذلك. من أشهر التراخيص المستخدمة:
- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, and LGPLv3.
يمكنك قراءة تفاصيل هذه التراخيص في الرابط: Open Source Initiative. في هذه الدروس سنستخدم ترخيص BSD لأن مكونات ROS الأخرى تستخدمه.
8 <license>BSD</license>
علامات المعتمدات
تقسم إلى عدة علامات: build_depend، buildtool_depend، exec_depend، test_depend. لمعرفة المزيد عنها انظر الرابط Catkin Dependencies. باعتبار أننا أضفنا المكتبات std_msgs، roscpp، rospy كقيم لتعليمة catkin_create_pkg، ستبدو علامات المعتمدات كما يلي::
27 <!-- The *_depend tags are used to specify dependencies -->
28 <!-- Dependencies can be catkin packages or system dependencies -->
29 <!-- Examples: -->
30 <!-- Use build_depend for packages you need at compile time: -->
31 <!-- <build_depend>genmsg</build_depend> -->
32 <!-- Use buildtool_depend for build tool packages: -->
33 <!-- <buildtool_depend>catkin</buildtool_depend> -->
34 <!-- Use exec_depend for packages you need at runtime: -->
35 <!-- <exec_depend>python-yaml</exec_depend> -->
36 <!-- Use test_depend for packages you need only for testing: -->
37 <!-- <test_depend>gtest</test_depend> -->
38 <buildtool_depend>catkin</buildtool_depend>
39 <build_depend>roscpp</build_depend>
40 <build_depend>rospy</build_depend>
41 <build_depend>std_msgs</build_depend>
كل المعتمدات قد أضيفت إلى علامة البناء build_depend، وإلى علامة أداء البناء buildtool_depend الخاصة بأداة catkin. ولأننا نحتاج أن تكون كل مكتباتنا متوافرة لمحلتي البناء والتشغيل، فقد أضيفت ايضاً إلىعلامة التشغيل exec_depend:
12 <buildtool_depend>catkin</buildtool_depend>
13
14 <build_depend>roscpp</build_depend>
15 <build_depend>rospy</build_depend>
16 <build_depend>std_msgs</build_depend>
17
18 <exec_depend>roscpp</exec_depend>
19 <exec_depend>rospy</exec_depend>
20 <exec_depend>std_msgs</exec_depend>
إنهاء package.xml
أخيراً يبدو ملف التوصيف package.xml بدون أي تعليقات كما يلي:
1 <?xml version="1.0"?>
2 <package format="2">
3 <name>beginner_tutorials</name>
4 <version>0.1.0</version>
5 <description>The beginner_tutorials package</description>
6
7 <maintainer email="you@yourdomain.tld">Your Name</maintainer>
8 <license>BSD</license>
9 <url type="website">http://wiki.ros.org/beginner_tutorials</url>
10 <author email="you@yourdomain.tld">Jane Doe</author>
11
12 <buildtool_depend>catkin</buildtool_depend>
13
14 <build_depend>roscpp</build_depend>
15 <build_depend>rospy</build_depend>
16 <build_depend>std_msgs</build_depend>
17
18 <exec_depend>roscpp</exec_depend>
19 <exec_depend>rospy</exec_depend>
20 <exec_depend>std_msgs</exec_depend>
21
22 </package>
تخصيص ملف البناء CMakeLists.txt
بعد الانتهاء من تخصيص ملف التوصيف package.xml الذي يحوي معلومات وسيطة، يمكنك الانتقال إلى تخصيص ملف البناء. إن الملف CMakeLists.txt الذي أنشأ باستخدام التعليمة catkin_create_pkg سيناقش في دروس لاحقة.
Now that you've made a new ROS package, let's build our ROS package.
Video Demonstration
Watch the video below to have more explanation on Custom Workspace and Package Creation with step by step guide .