美文网首页
ROS-I simple_message 源码分析:RobotS

ROS-I simple_message 源码分析:RobotS

作者: play_robot | 来源:发表于2019-03-21 15:59 被阅读0次

在了解TypedMessage后,我们就可以开始为每种数据类型创建这样的message类了。这里说的数据类型正是指代我们之前文章中的那些类,同时也与SimpleMessage协议中定义的枚举消息类型对应,回顾一下我们分析了哪些数据类型吧:

也就是说我们需要为每种数据类型从TypedMessage继承创建一个与之对应的message类,在这个类中封装该数据类型,并实现TypedMessage中定义的init接口,相当于扩展了以上原有类的功能。我们看一个例子:

RobotStatusMessage

namespace industrial
{
namespace robot_status_message
{

class RobotStatusMessage : public industrial::typed_message::TypedMessage
{
public:

  RobotStatusMessage(void);
  ~RobotStatusMessage(void);

  bool init(industrial::simple_message::SimpleMessage & msg);
  void init(industrial::robot_status::RobotStatus & status);
  void init();


  // Overrides - SimpleSerialize
  bool load(industrial::byte_array::ByteArray *buffer);
  bool unload(industrial::byte_array::ByteArray *buffer);

  unsigned int byteLength()
  {
    return this->status_.byteLength();
  }
  

  industrial::robot_status::RobotStatus status_;

};

}
}

上面的RobotStatusMessage类继承自TypedMessage,封装了RobotStatus对象,我们需要实现init方法(当然,由于TypedMessage继承自SimpleSerialize,RobotStatusMessage还要实现load和unload方法,在load和unload中又将会触发被wrap的数据结构(本例中是RobotStatus)的load和unload)

bool RobotStatusMessage::init(industrial::simple_message::SimpleMessage & msg)
{
  bool rtn = false;
  //获取msg中的data
  ByteArray data = msg.getData();
  this->init(); //设置消息类型,初始化封装的数据成员status_
  //设置通信类型
  this->setCommType(msg.getCommType());
  //从data中卸载数据至数据成员status_
  if (data.unload(this->status_))
  {
    rtn = true;
  }
  else
  {
    LOG_ERROR("Failed to unload robot status data");
  }
  return rtn;
}

void RobotStatusMessage::init(industrial::robot_status::RobotStatus & status)
{
  this->init();
  this->status_.copyFrom(status);
}

void RobotStatusMessage::init()
{
  this->setMessageType(StandardMsgTypes::STATUS);
  this->status_.init();
}

经过init调用后,就可以从已有的SimpleMessage对象解包,初始化了RobotStatusMessage。
那么如何生成SimpleMessage呢?我们再看一下接口中的如下三个方法:

  virtual bool toRequest(industrial::simple_message::SimpleMessage & msg)
  {
      industrial::byte_array::ByteArray data;
      data.load(*this);
      return msg.init(this->getMessageType(),
              industrial::simple_message::CommTypes::SERVICE_REQUEST,
              industrial::simple_message::ReplyTypes::INVALID, data);
  }

  virtual bool toReply(industrial::simple_message::SimpleMessage & msg,
          industrial::simple_message::ReplyType reply)
  {
      industrial::byte_array::ByteArray data;
    data.load(*this);
    return msg.init(this->getMessageType(),
            industrial::simple_message::CommTypes::SERVICE_REPLY,
            reply, data);
  }

  virtual bool toTopic(industrial::simple_message::SimpleMessage & msg)
  {
      industrial::byte_array::ByteArray data;
    data.load(*this);
    return msg.init(this->getMessageType(),
            industrial::simple_message::CommTypes::TOPIC,
            industrial::simple_message::ReplyTypes::INVALID, data);
  }

以toRequest为例,该方法先将对象的数据加载至临时的ByteArray类型的data变量,而后调用SimpleMessage的init方法,将有效数据填充至msg。这样就完成了创建SimpleMessage的功能。

简而言之,TypedMessage作为SimpleMessage和可序列化的RobotStatus的中间层,实现了双向的数据转换。


TypedMessage

相关文章

网友评论

      本文标题:ROS-I simple_message 源码分析:RobotS

      本文链接:https://www.haomeiwen.com/subject/hxccvqtx.html