Go to the documentation of this file.00001
00023 #ifndef BLACKBOARD_H_
00024 #define BLACKBOARD_H_
00025
00026 #include <iostream>
00027 #include <ros/ros.h>
00028
00029 #include "micros_swarm/singleton.h"
00030 #include "micros_swarm/packet_type.h"
00031 #include "micros_swarm/serialize.h"
00032 #include "micros_swarm/runtime_handle.h"
00033 #include "micros_swarm/msg_queue_manager.h"
00034 #include "gsdf_msgs/CommPacket.h"
00035 #include "gsdf_msgs/BlackBoardPut.h"
00036 #include "gsdf_msgs/BlackBoardQuery.h"
00037 #include "gsdf_msgs/BlackBoardAck.h"
00038
00039 namespace micros_swarm{
00040
00041 template<class Type>
00042 class BlackBoard{
00043 public:
00044 BlackBoard()
00045 {
00046 bb_id_ = -1;
00047 on_robot_id_ = -1;
00048 robot_id_ = -1;
00049 is_local_ = false;
00050 }
00051
00052 BlackBoard(int bb_id, int on_robot_id)
00053 {
00054 bb_id_ = bb_id;
00055 on_robot_id_ = on_robot_id;
00056 rth_ = Singleton<RuntimeHandle>::getSingleton();
00057 robot_id_ = rth_->getRobotID();
00058 mqm_ = Singleton<MsgQueueManager>::getSingleton();
00059 is_local_ = false;
00060 if(on_robot_id_ == robot_id_) {
00061 rth_->createBlackBoard(bb_id_);
00062 is_local_ = true;
00063 }
00064 }
00065
00066 BlackBoard(const BlackBoard& bb)
00067 {
00068 rth_ = Singleton<RuntimeHandle>::getSingleton();
00069 mqm_ = Singleton<MsgQueueManager>::getSingleton();
00070 bb_id_ = bb.bb_id_;
00071 on_robot_id_ = bb.on_robot_id_;
00072 robot_id_ = bb.robot_id_;
00073 is_local_ = bb.is_local_;
00074 }
00075
00076 BlackBoard& operator=(const BlackBoard& bb)
00077 {
00078 if(this == &bb) {
00079 return *this;
00080 }
00081 rth_ = Singleton<RuntimeHandle>::getSingleton();
00082 mqm_ = Singleton<MsgQueueManager>::getSingleton();
00083 bb_id_ = bb.bb_id_;
00084 on_robot_id_ = bb.on_robot_id_;
00085 robot_id_ = bb.robot_id_;
00086 is_local_ = bb.is_local_;
00087 return *this;
00088 }
00089
00090 ~BlackBoard()
00091 {
00092 rth_.reset();
00093 mqm_.reset();
00094 }
00095
00096 void put(const std::string& key, const Type& data)
00097 {
00098 std::vector<uint8_t> s = serialize_ros(data);
00099 ros::Time timestamp = ros::Time::now();
00100 if(is_local_) {
00101 rth_->insertOrUpdateBlackBoard(bb_id_, key, s, timestamp, rth_->getRobotID());
00102 }
00103 else {
00104 gsdf_msgs::BlackBoardPut bbp;
00105 bbp.bb_id = bb_id_;
00106 bbp.on_robot_id = on_robot_id_;
00107 bbp.key = key;
00108 bbp.value = s;
00109 bbp.timestamp = timestamp;
00110 bbp.robot_id = rth_->getRobotID();
00111 std::vector<uint8_t> bbp_vec = serialize_ros(bbp);
00112
00113 gsdf_msgs::CommPacket p;
00114 p.header.source = rth_->getRobotID();
00115 p.header.type = BLACKBOARD_PUT;
00116 p.header.data_len = bbp_vec.size();
00117 p.header.version = 1;
00118 p.header.checksum = 0;
00119 p.content.buf = bbp_vec;
00120 std::vector<uint8_t> msg_data = serialize_ros(p);
00121 mqm_->getOutMsgQueue("bb")->push(msg_data);
00122 }
00123 }
00124
00125 Type get(const std::string& key)
00126 {
00127 if(is_local_) {
00128 BlackBoardTuple bb;
00129 rth_->getBlackBoardTuple(bb_id_, key, bb);
00130
00131 if ((bb.timestamp.sec == 0) && (bb.timestamp.nsec == 0)) {
00132 std::cout << "ID " << bb_id_ << " blackboard, " << key << " is not exist." << std::endl;
00133 exit(-1);
00134 }
00135
00136 Type data = deserialize_ros<Type>(bb.bb_value);
00137 return data;
00138 }
00139 else {
00140 gsdf_msgs::BlackBoardQuery bbq;
00141 bbq.bb_id = bb_id_;
00142 bbq.on_robot_id = on_robot_id_;
00143 bbq.key = key;
00144 bbq.timestamp = ros::Time::now();
00145 bbq.robot_id = robot_id_;
00146 std::vector<uint8_t> bbq_vec = serialize_ros(bbq);
00147
00148 gsdf_msgs::CommPacket p;
00149 p.header.source = rth_->getRobotID();
00150 p.header.type = BLACKBOARD_QUERY;
00151 p.header.data_len = bbq_vec.size();
00152 p.header.version = 1;
00153 p.header.checksum = 0;
00154 p.content.buf = bbq_vec;
00155 rth_->createBlackBoard(bb_id_);
00156 ros::Time timestamp;
00157 timestamp.sec = 0;
00158 timestamp.nsec = 0;
00159 std::vector<uint8_t> empty_vec;
00160 empty_vec.clear();
00161 rth_->insertOrUpdateBlackBoard(bb_id_, key, empty_vec, timestamp, -1);
00162 std::vector<uint8_t> msg_data = serialize_ros(p);
00163 mqm_->getOutMsgQueue("bb")->push(msg_data);
00164
00165 Type data;
00166 BlackBoardTuple bbt;
00167 ros::Rate loop_rate(100);
00168 int count = 0;
00169 while(count < 500) {
00170 rth_->getBlackBoardTuple(bb_id_, key, bbt);
00171 if(bbt.bb_value.size() != 0) {
00172 data = deserialize_ros<Type>(bbt.bb_value);
00173 rth_->deleteBlackBoardValue(bb_id_, key);
00174 break;
00175 }
00176 loop_rate.sleep();
00177 ros::spinOnce();
00178 }
00179
00180 return data;
00181 }
00182 }
00183
00184 int size()
00185 {
00186 if(is_local_) {
00187 return rth_->getBlackBoardSize(bb_id_);
00188 }
00189 else {
00190
00191 }
00192 }
00193 private:
00194 int robot_id_;
00195 int bb_id_;
00196 int on_robot_id_;
00197 bool is_local_;
00198 boost::shared_ptr<RuntimeHandle> rth_;
00199 boost::shared_ptr<micros_swarm::MsgQueueManager> mqm_;
00200 };
00201 }
00202 #endif