当前位置:   article > 正文

如何在ROS中定义并使用自己的消息类型-以image类型为例_ros image

ros image
ROS自带的消息类型非常丰富,在ROS Kinetic上使用命令rostopic list可以查看所有的消息类型。但是总有时候系统自带的消息类型无法满足工程的特殊需要,这时我们可以自定义消息类型。

   我们要在板子上测试其图像处理能力,要使用一个image_buf的类型进行cache,iamge_buf是一个image的vector。这里,我们直接自己定义一个image类型,然后生成对应的消息类型,并根据这个image,再生成image_buf。

自定义第一个消息类型my_imgdata

1. 建立自定义消息类型package

   cd ~/catkin_ws/src/

   catkin_creat_pkg imgdata_msg

   cd imgdata_msg/

   mkdir msg

2. 输入消息格式到消息文件,这里图像数据格式参考:http://blog.csdn.net/redskydeng/article/details/49362155

   echo "uint8[] data" >> msg/my_imgdata.msg

    echo "string actor_time" >> msg/my_imgdata.msg

3. 在imgdata_msg的CMakeLists.txt文件中添加如下语句

  find_package(catkin REQUIRED COMPONENTS message_generation roscpp std_msgs)

4. 取消 add_message_files 的相关注释,并添加为如下:
   add_message_files(FILES my_imgdata.msg )

5. 取消generate_messages的相关注释,并添加修改为如下:
   generate_messages(DEPENDENCIES std_msgs  )

6. 在catkin_package中添加:CATKIN_DEPENDS message_runtime

7. 在imgdata_msg的.xml文件中添加://indigo用的是run_depend,为Kinetic用的是exec_depend

  <build_depend>message_generation</build_depend>

  <exec_depend>message_runtime</exec_depend>

8. cd ~/catkin_ws/  &&  catkin_make -DCATKIN_WHITELIST_PACKAGES="imgdata_msg"

9. source devel/setup.bash

10. 至此第一个自定义的消息定义完成,你可以用rosmsg(在indigo上是rostopic)查看完整的消息定义

    rosmsg show imgdata_msg/my_imgdata


下面建立第二个消息类型Img_buf,该消息会使用之前我们自定义的消息类型my_imgdata

1. cd ~/catkin_ws/src/imgdata_msg/ 

2. 输入消息格式到消息文件

    echo "std_msgs/Header  header" >> msg/Img_buf.msg

    echo "imgdata_msg/my_imgdata[]  buf" >> msg/Img_buf.msg

3. 在建立第一个消息的基础上,在 add_message_files 添加如下红色部分:
   add_message_files(FILES my_imgdata.msg Img_buf.msg )

4. cd ~/catkin_ws/  &&  catkin_make -DCATKIN_WHITELIST_PACKAGES="imgdata_msg"


5 source devel/setup.bash

6 至此第一个自定义的消息定义完成,你可以用rosmsg show imgdata_msg/Img_buf 查看完整的消息定义


使用自定义的消息类型:

在使用该消息的工程中添加如下头文件即可,同时要把devel/include目录下的imgdata_msg整体复制到使用该消息的include目录下

#include <imgdata_msg/Img_buf.h>

该头文件是系统在建立自定义消息类型时候自动生成的。


这次实践,自己定义了一个消息类型my_imgdata,里面包含一个数组(或者说是vector)和一个string,然后又针对my_imgdata封装了一个新的消息类型Img_buf,里面包含了一个my_imgdata的数组(或者说是vector)。虽然这次实践的内容看来可能没有实际意义,(定义一个消息类型,又定义一个该消息类型的vetor作为一个新的消息类型)但是我们的最终目标是根据别人提供的任何消息类型,进行二次封装(目的是为了实现缓存),往里面再添加一些其他的成员,如时间、长度等信息,然后就可以利用ros提供的序列化和反序列化,这样就可以不考虑别人提供的数据(这部分数据也有序列化和反序列化)。

这里给出我们这次写出来的测试程序:

  1. #include <memory>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <string>
  5. #include <pthread.h>
  6. #include <map>
  7. #include <fstream>
  8. #include <iostream>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #include <sys/time.h>
  12. #include "zlib.h"
  13. #include "LRUCache.hpp"
  14. #include "imgdata_msg/Img_buf.h"
  15. #include "imgdata_msg/my_imgdata.h"
  16. #define MAX_BUF 100
  17. #define STORE_PATH "/home/oldking/Msg-File/"
  18. using std::string;
  19. using std::vector;
  20. imgdata_msg::Img_buf w_buf;
  21. pthread_mutex_t buf_lock;
  22. lru::Cache<std::string, imgdata_msg::Img_buf> cache(5,0);//first param is cache size
  23. unsigned long ReadFromFile(std::string file_name, unsigned char*& data)
  24. {
  25. std::ifstream rs(file_name.c_str(), std::ios::binary);
  26. rs.seekg(0, std::ios_base::end);
  27. unsigned long length = rs.tellg();
  28. rs.seekg(0, std::ios_base::beg);
  29. data = new unsigned char[length];
  30. rs.read((char*)data, length);
  31. rs.close();
  32. return length;
  33. }
  34. int ForceWrite()
  35. {
  36. mode_t mode = 0755;
  37. mkdir(STORE_PATH, mode);
  38. size_t serial_size = ros::serialization::serializationLength(w_buf);
  39. boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
  40. ros::serialization::OStream stream(buffer.get(), serial_size);
  41. ros::serialization::serialize(stream, w_buf);
  42. unsigned char* write = buffer.get();
  43. uLong comprLen = compressBound(serial_size);
  44. Byte *compr = new Byte[comprLen];
  45. int err;
  46. err = compress(compr, &comprLen, (const Bytef*)write, serial_size);
  47. if(err != Z_OK)
  48. {
  49. printf("compress write file failed !\n");
  50. return 1;
  51. }
  52. std::string file_name = STORE_PATH + w_buf.write_buffer[0].actor_time;
  53. printf("file_name : %s\n", file_name.c_str());
  54. //std::ofstream rs(file_name.c_str(), std::ios::binary);
  55. //rs.write((const char*)compr, comprLen);
  56. //rs.close();
  57. FILE* file;
  58. if((file = fopen(file_name.c_str(), "wb")) == NULL)
  59. {
  60. printf("cannot create %s!\n", file_name.c_str());
  61. return -1;
  62. }
  63. uLong flen = serial_size;
  64. fwrite(&flen, sizeof(uLong), 1, file);
  65. fwrite(&comprLen, sizeof(uLong), 1, file);
  66. fwrite(compr, sizeof(unsigned char), comprLen, file);
  67. fclose(file);
  68. delete[] compr;
  69. //Initialize vector
  70. w_buf.write_buffer.clear();
  71. //w_buf.num = 0;
  72. return 0;
  73. }
  74. int InsertToBuffer(imgdata_msg::my_imgdata &Msg)
  75. {
  76. if(w_buf.write_buffer.size() < MAX_BUF)
  77. {
  78. pthread_mutex_lock(&buf_lock);
  79. w_buf.write_buffer.push_back(Msg);
  80. //w_buf.num += 1;//我们没有这个变量
  81. pthread_mutex_unlock(&buf_lock);
  82. if(w_buf.write_buffer.size() == MAX_BUF)
  83. ForceWrite();
  84. }
  85. else
  86. {
  87. ForceWrite();
  88. pthread_mutex_lock(&buf_lock);
  89. w_buf.write_buffer.push_back(Msg);
  90. // w_buf.num += 1;
  91. pthread_mutex_unlock(&buf_lock);
  92. }
  93. return 0;
  94. }
  95. int MsgStore(imgdata_msg::my_imgdata &Msg)
  96. {
  97. InsertToBuffer(Msg);
  98. return 0;
  99. }
  100. int BufRead(string file_name, vector<imgdata_msg::my_imgdata> &MsgVec)
  101. {
  102. imgdata_msg::Img_buf data;
  103. if(cache.contains(file_name))
  104. {
  105. data = cache.get(file_name);
  106. }
  107. else
  108. {
  109. uLong flen;
  110. unsigned char* fbuf = NULL;
  111. uLong ulen;
  112. unsigned char* ubuf = NULL;
  113. FILE *file;
  114. if((file = fopen(file_name.c_str(), "rb")) == NULL)
  115. {
  116. printf("Can\'t open %s!\n", file_name.c_str());
  117. return -1;
  118. }
  119. fread(&ulen, sizeof(uLong), 1, file);
  120. fread(&flen, sizeof(uLong), 1, file);
  121. if((fbuf = (unsigned char*)malloc(sizeof(unsigned char) * flen)) == NULL)
  122. {
  123. printf("No enough memory!\n");
  124. fclose(file);
  125. return -1;
  126. }
  127. fread(fbuf, sizeof(unsigned char), flen, file);
  128. if((ubuf = (unsigned char*)malloc(sizeof(unsigned char) * ulen)) == NULL)
  129. {
  130. printf("No enough memory!\n");
  131. fclose(file);
  132. return -1;
  133. }
  134. if(uncompress(ubuf, &ulen, fbuf, flen) != Z_OK)
  135. {
  136. printf("Uncompress failed!\n");
  137. return -1;
  138. }
  139. fclose(file);
  140. ros::serialization::IStream stream((uint8_t*)ubuf, ulen);
  141. ros::serialization::Serializer<imgdata_msg::Img_buf>::read(stream, data);
  142. cache.insert(file_name, data);
  143. delete[] ubuf;
  144. delete[] fbuf;
  145. }
  146. long i;
  147. for(i=0;i<data.write_buffer.size();i++)
  148. MsgVec.push_back(data.write_buffer[i]);
  149. return 0;
  150. }
  151. int main()
  152. {
  153. long i;
  154. std::string actor_time = "201803";
  155. timeval write_time_start,write_time_end;
  156. gettimeofday(&write_time_start, NULL);
  157. for(i=0;i<1000;i++)
  158. {
  159. imgdata_msg::my_imgdata tmp;
  160. /*tmp.uav_pose.position.x=i+0.4;
  161. tmp.uav_pose.position.y=i+0.6;
  162. tmp.uav_pose.position.z=i+0.3;
  163. tmp.uav_pose.orientation.x=i+0.9;
  164. tmp.uav_pose.orientation.y=i+0.2;
  165. tmp.uav_pose.orientation.z=i+0.4;
  166. tmp.uav_pose.orientation.w=i+0.2;
  167. tmp.sensor_pose.position.x=i+0.4;
  168. tmp.sensor_pose.position.y=i+0.6;
  169. tmp.sensor_pose.position.z=i+0.3;
  170. tmp.sensor_pose.orientation.x=i+0.9;
  171. tmp.sensor_pose.orientation.y=i+0.2;
  172. tmp.sensor_pose.orientation.z=i+0.4;
  173. tmp.sensor_pose.orientation.w=i+0.2;*/
  174. tmp.actor_time = actor_time + std::to_string(i);
  175. /*
  176. tmp.sensor_msg.header.seq=1;
  177. tmp.sensor_msg.header.stamp.sec=1;
  178. tmp.sensor_msg.header.stamp.nsec=1;
  179. tmp.sensor_msg.status.status=1;
  180. tmp.sensor_msg.status.service=2;
  181. tmp.sensor_msg.latitude=1.0;
  182. tmp.sensor_msg.longitude=2.0;
  183. */
  184. int a;
  185. long j;
  186. for(j=0;j<30000;j++)
  187. {
  188. //tmp.data[j]=100;
  189. a=100;
  190. tmp.data.push_back(a);
  191. }
  192. //tmp.sensor_msg.position_covariance_type=0;
  193. MsgStore(tmp);//write into file
  194. }
  195. gettimeofday(&write_time_end, NULL);
  196. long write_time = 1000000 * ( write_time_end.tv_sec - write_time_start.tv_sec ) + write_time_end.tv_usec - write_time_start.tv_usec;
  197. printf("write_time : %ld\n", write_time);
  198. /*
  199. long read_time = 0;
  200. timeval read_time_start;
  201. timeval read_time_end;
  202. std::vector<imgdata_msg::my_imgdata> result;
  203. gettimeofday(&read_time_start, NULL);
  204. BufRead("/home/olding/Msg-File/201803100", result);
  205. gettimeofday(&read_time_end, NULL);
  206. read_time = 1000000 * ( read_time_end.tv_sec - read_time_start.tv_sec ) + read_time_end.tv_usec - read_time_start.tv_usec;
  207. printf("read_time : %ld\n", read_time);
  208. result.clear();
  209. gettimeofday(&read_time_start, NULL);
  210. BufRead("/home/oldking/Msg-File/201803100", result);
  211. gettimeofday(&read_time_end, NULL);
  212. read_time = 1000000 * ( read_time_end.tv_sec - read_time_start.tv_sec ) + read_time_end.tv_usec - read_time_start.tv_usec;
  213. printf("read_time : %ld\n", read_time);
  214. */
  215. return 0;
  216. }

参考:http://blog.csdn.net/u011906844/article/details/72156215

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/540499
推荐阅读
相关标签
  

闽ICP备14008679号