ROS与C++入门教程-消息-序列化和适配类型
ROS与C++入门教程-消息-序列化和适配类型
说明:
- 介绍序列化和适配类型
- 在C Turtle版本增加
序列化到内存
- 使用ros::serialization::serialize()函数,roscpp的消息能非常容易地序列化到内存。
- 示例:
namespace ser = ros::serialization;
std_msgs::UInt32 my_value;
my_value.data = 5;
uint32_t serial_size = ros::serialization::serializationLength(my_value);
boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
ser::OStream stream(buffer.get(), serial_size);
ser::serialize(stream, my_value);
从内存中反序列
- 从内存中反序列,也很容易:
namespace ser = ros::serialization;
std_msgs::UInt32 my_value;
uint32_t serial_size = ros::serialization::serializationLength(my_value);
boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
// Fill buffer with a serialized UInt32
ser::IStream stream(buffer.get(), serial_size);
ser::deserialize(stream, my_value);
- 在最新ROS,上面代码会显示deprecation warning,替换最后一行为:
ros::serialization::Serializer<std_msgs::UInt32>::read(stream, my_value);
适配C++类型
- 在ROS 1.1,roscpp使用了基于模板的序列化系统。
- 它能适应外部类型,能在ROS的订阅和发布中使用。
- 它通过一套专门的特性类,以及一个专门的序列化类来实现。
Trait Specialization
- 针对发布和订阅的特征,可以查阅message traits
Serializer Specialization
- 为了定义类型的序列化,你必需定义ros::serialization::Serializer类的specialization
- 示例代码:
template<typename T>
struct Serializer
{
template<typename Stream>
inline static void write(Stream& stream, typename boost::call_traits<T>::param_type t);
template<typename Stream>
inline static void read(Stream& stream, typename boost::call_traits<T>::reference t);
inline static uint32_t serializedLength(typename boost::call_traits<T>::param_type t);
};
- 定义all-in-one序列处理器
template<typename T>
struct Serializer
{
template<typename Stream, typename M>
inline static void allInOne(Stream& stream, M t);
ROS_DECLARE_ALLINONE_SERIALIZER;
};
- 注意,如果你使用一个all-in-one序列处理器,不允许你其他函数,除了stream.next()。
- 任何需要更复杂的行为应使用独立的3-function版本。
适配自定义Vector3
- 想适配自己的vector struct使用roscpp , 请查阅geometry_msgs/Vector3:
- 示例代码:
#include <ros/message_traits.h>
#include <ros/serialization.h>
struct MyVector3
{
double x;
double y;
double z;
};
// compile-time assert that sizeof(MyVector3) == serializationLength(x) + serializationLength(y) + serializationLength(z)
ROS_STATIC_ASSERT(sizeof(MyVector3) == 24);
namespace ros
{
namespace message_traits
{
// This type is fixed-size (24-bytes)
template<> struct IsFixedSize<MyVector3> : public TrueType {};
// This type is memcpyable
template<> struct IsSimple<MyVector3> : public TrueType {};
template<>
struct MD5Sum<MyVector3>
{
static const char* value()
{
// Ensure that if the definition of geometry_msgs/Vector3 changes we have a compile error here.
ROS_STATIC_ASSERT(MD5Sum<geometry_msgs::Vector3>::static_value1 == 0x4a842b65f413084dULL);
ROS_STATIC_ASSERT(MD5Sum<geometry_msgs::Vector3>::static_value2 == 0xc2b10fb484ea7f17ULL);
return MD5Sum<geometry_msgs::Vector3>::value();
}
static const char* value(const MyVector3& m)
{
return MD5Sum<geometry_msgs::Vector3>::value(m);
}
};
template<>
struct DataType<MyVector3>
{
static const char* value()
{
return DataType<geometry_msgs::Vector3>::value();
}
static const char* value(const MyVector3& m)
{
return DataType<geometry_msgs::Vector3>::value(m);
}
};
template<>
struct Definition<MyVector3>
{
static const char* value()
{
return Definition<geometry_msgs::Vector3>::value();
}
static const char* value(const MyVector3& m)
{
return Definition<geometry_msgs::Vector3>::value(m);
}
};
} // namespace message_traits
namespace serialization
{
template<>
struct Serializer<MyVector3>
{
template<typename Stream, typename T>
inline static void allInOne(Stream& stream, T t)
{
stream.next(t.x);
stream.next(t.y);
stream.next(t.z);
}
ROS_DECLARE_ALLINONE_SERIALIZER;
};
} // namespace serialization
} // namespace ros
- 替换成使用3-function序列处理:
namespace ros
{
namespace serialization
{
template<>
struct Serializer<MyVector3>
{
template<typename Stream>
inline static void write(Stream& stream, const MyVector3& t)
{
stream.next(t.x);
stream.next(t.y);
stream.next(t.z);
}
template<typename Stream>
inline static void read(Stream& stream, MyVector3& t)
{
stream.next(t.x);
stream.next(t.y);
stream.next(t.z);
}
inline static uint32_t serializedLength(const MyVector3& t)
{
uint32_t size = 0;
size += serializationLength(t.x);
size += serializationLength(t.y);
size += serializationLength(t.z);
return size;
}
};
} // namespace serialization
} // namespace ros
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号