小猫

版主
  • 主题:39
  • 回复:39
  • 金钱:132
  • 积分:181
本帖最后由 Crazy_GF 于 2014-8-7 09:31 编辑

ROS库中本身带有kinect的驱动和应用包,但是很难应用到嵌入式系统当中,但是单独的openni库已经很完善了,很容易应用在PC机和嵌入式系统当中。为了在嵌入式的ARM系统中应用ROS和kinect,首先我在PC机上进行ROS链接openni库的实验。
       一、安装openni库

       二、建立kinect_test包
       首先建立一个ROS的package,然后在src文件夹下建立代码文件,结合ROS教程中WritingPublisherSubscriber(C++)一章中的编程方法和openni中samples里的NiSimpleRead例程代码,使用openni库中的功能函数获取kinect数据,并使用ROS进行消息发布。代码如下(代码包下载请见http://download.csdn.net/detail/hcx25909/5093853):
        1、kinect_value_talker.cpp
[cpp] view plaincopy

  1. <span style="font-size:14px;">/****************************************************************************
  2. *                                                                           *
  3. *  OpenNI 1.x Alpha                                                         *
  4. *  Copyright (C) 2011 PrimeSense Ltd.                                       *
  5. *                                                                           *
  6. *  This file is part of OpenNI.                                             *
  7. *                                                                           *
  8. *  OpenNI is free software: you can redistribute it and/or modify           *
  9. *  it under the terms of the GNU Lesser General Public License as published *
  10. *  by the Free Software Foundation, either version 3 of the License, or     *
  11. *  (at your option) any later version.                                      *
  12. *                                                                           *
  13. *  OpenNI is distributed in the hope that it will be useful,                *
  14. *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
  15. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
  16. *  GNU Lesser General Public License for more details.                      *
  17. *                                                                           *
  18. *  You should have received a copy of the GNU Lesser General Public License *
  19. *  along with OpenNI. If not, see <http://www.gnu.org/licenses/>.           *
  20. *                                                                           *
  21. ****************************************************************************/  
  22. //---------------------------------------------------------------------------  
  23. // Includes  
  24. //---------------------------------------------------------------------------  
  25. #include <XnOpenNI.h>  
  26. #include <XnLog.h>  
  27. #include <XnCppWrapper.h>  
  28. #include <XnFPSCalculator.h>  
  29.   
  30. #include "ros/ros.h"  
  31. #include "std_msgs/String.h"  
  32.   
  33. #include <sstream>  
  34.   
  35. //---------------------------------------------------------------------------  
  36. // Defines  
  37. //---------------------------------------------------------------------------  
  38. #define SAMPLE_XML_PATH "Data/SamplesConfig.xml"  
  39.   
  40. //---------------------------------------------------------------------------  
  41. // Macros  
  42. //---------------------------------------------------------------------------  
  43. #define CHECK_RC(rc, what)                                          \  
  44.     if (rc != XN_STATUS_OK)                                         \  
  45.     {                                                               \  
  46.         printf("%s failed: %s\n", what, xnGetStatusString(rc));     \  
  47.         return rc;                                                  \  
  48.     }  
  49.   
  50. //---------------------------------------------------------------------------  
  51. // Code  
  52. //---------------------------------------------------------------------------  
  53. using namespace xn;  
  54.   
  55. XnBool fileExists(const char *fn)  
  56. {  
  57.     XnBool exists;  
  58.     xnOSDoesFileExist(fn, &exists);  
  59.     return exists;  
  60. }  
  61.   
  62. int main(int argc, char **argv)  
  63. {  
  64.     XnStatus nRetVal = XN_STATUS_OK;  
  65.   
  66.     Context context;  
  67.     ScriptNode scriptNode;  
  68.     EnumerationErrors errors;  
  69.   
  70.     ros::init(argc, argv, "talker");  
  71.     ros::NodeHandle n;  
  72.     ros::Publisher chatter_pub = n.advertise<std_msgs::String>("kinect_value", 1000);  
  73.     ros::Rate loop_rate(10);  
  74.   
  75.     const char *fn = NULL;  
  76.   
  77.     if  (fileExists(SAMPLE_XML_PATH)) fn = SAMPLE_XML_PATH;  
  78.     else {  
  79.         printf("Could not find '%s'. Aborting.\n" , SAMPLE_XML_PATH);  
  80.         return XN_STATUS_ERROR;  
  81.     }  
  82.     printf("Reading config from: '%s'\n", fn);  
  83.   
  84.     nRetVal = context.InitFromXmlFile(fn, scriptNode, &errors);  
  85.   
  86.     if (nRetVal == XN_STATUS_NO_NODE_PRESENT)  
  87.     {  
  88.         XnChar strError[1024];  
  89.         errors.ToString(strError, 1024);  
  90.         printf("%s\n", strError);  
  91.         return (nRetVal);  
  92.     }  
  93.     else if (nRetVal != XN_STATUS_OK)  
  94.     {  
  95.         printf("Open failed: %s\n", xnGetStatusString(nRetVal));  
  96.         return (nRetVal);  
  97.     }  
  98.   
  99.     DepthGenerator depth;  
  100.     nRetVal = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);  
  101.     CHECK_RC(nRetVal, "Find depth generator");  
  102.   
  103.     XnFPSData xnFPS;  
  104.     nRetVal = xnFPSInit(&xnFPS, 180);  
  105.     CHECK_RC(nRetVal, "FPS Init");  
  106.   
  107.     DepthMetaData depthMD;  
  108.    
  109.     while ((!xnOSWasKeyboardHit()) && (ros::ok()))  
  110.     {  
  111.         std_msgs::String msg;  
  112.         std::stringstream ss;  
  113.   
  114.         nRetVal = context.WaitOneUpdateAll(depth);  
  115.         if (nRetVal != XN_STATUS_OK)  
  116.         {  
  117.             printf("UpdateData failed: %s\n", xnGetStatusString(nRetVal));  
  118.             continue;  
  119.         }  
  120.   
  121.         xnFPSMarkFrame(&xnFPS);  
  122.   
  123.         depth.GetMetaData(depthMD);  
  124.         const XnDepthPixel* pDepthMap = depthMD.Data();  
  125.   
  126.         ss << "Frame " << depthMD.FrameID();  
  127.         ss << "  Middle point is: " <<  depthMD(depthMD.XRes() / 2, depthMD.YRes() / 2);  
  128.         ss << "  FPS: " << xnFPSCalc(&xnFPS);  
  129.         msg.data = ss.str();  
  130.   
  131.         ROS_INFO("%s", msg.data.c_str());  
  132.   
  133.         chatter_pub.publish(msg);  
  134.   
  135.         ros::spinOnce();  
  136.         loop_rate.sleep();  
  137.     }  
  138.   
  139.     depth.Release();  
  140.     scriptNode.Release();  
  141.     context.Release();  
  142.   
  143.     return 0;  
  144. }</span><span style="font-size: 18px;">  
  145. </span>  
复制代码

2、kinect_value_listener.cpp

[cpp] view plaincopy

  1. <span style="font-size:14px;">#include "ros/ros.h"  
  2. #include "std_msgs/String.h"  
  3.   
  4. /**
  5. * This tutorial demonstrates simple receipt of messages over the ROS system.
  6. */  
  7. void chatterCallback(const std_msgs::String::ConstPtr& msg)  
  8. {  
  9.   ROS_INFO("I heard: [%s]", msg->data.c_str());  
  10. }  
  11.   
  12. int main(int argc, char **argv)  
  13. {  
  14.   ros::init(argc, argv, "listener");  
  15.   ros::NodeHandle n;  
  16.   
  17.   ros::Subscriber sub = n.subscribe("kinect_value", 1000, chatterCallback);  
  18.   
  19.   ros::spin();  
  20.   
  21.   return 0;  
  22. }</span>  
复制代码

参考链接:http://www.ros.org/wiki/ROS/Tuto ... criber%28c%2B%2B%29

三、修改编译文件
       首先在CMakeLists.txt中将程序和openni库进行链接。在文件中加入头文件路径:
[plain] view plaincopy
1.        <span style="font-size:14px;">include_directories ("/usr/include/ni/")</span>  
       加入编译的文件和链接的库
[plain] view plaincopy
  1. <span style="font-size:14px;">rosbuild_add_executable(kinect_value_talker   src/kinect_value_talker.cpp)  
  2. rosbuild_add_executable(kinect_value_listener src/kinect_value_listener.cpp)  
  3. target_link_libraries(kinect_value_talker OpenNI)</span>      
复制代码
然后进行rosmake编译。
        实验结果: