美文网首页
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