00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <rosmatlab/rosbag/bag.h>
00030 #include <rosmatlab/conversion.h>
00031 #include <rosmatlab/connection_header.h>
00032 #include <rosmatlab/log.h>
00033
00034 #include <rosmatlab/rosbag/view.h>
00035
00036 #include <introspection/message.h>
00037
00038 namespace rosmatlab {
00039 namespace rosbag {
00040
00041 template <> const char *Object<Bag>::class_name_ = "rosbag.Bag";
00042
00043 Bag::Bag()
00044 : Object<Bag>(this)
00045 {
00046 }
00047
00048 Bag::Bag(int nrhs, const mxArray *prhs[])
00049 : Object<Bag>(this)
00050 {
00051 if (nrhs > 0) open(nrhs, prhs);
00052 }
00053
00054 Bag::~Bag() {
00055 close();
00056 }
00057
00058 void Bag::open(int nrhs, const mxArray *prhs[])
00059 {
00060 if (nrhs < 1) throw ArgumentException("Bag.open", 1);
00061 std::string filename = Options::getString(prhs[0]);
00062 uint32_t mode = ::rosbag::bagmode::Read;
00063
00064 if (nrhs >= 2) {
00065 mode = Options::getIntegerScalar(prhs[1]);
00066 if (mode > 7) throw Exception("Bag.open", "Invalid value for mode");
00067 }
00068
00069 try {
00070 ::rosbag::Bag::open(filename, mode);
00071 } catch(std::runtime_error &e) {
00072 throw Exception(e);
00073 }
00074 }
00075
00076 void Bag::close()
00077 {
00078 ::rosbag::Bag::close();
00079 }
00080
00081 void Bag::data(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00082 {
00083 View view(*this, nrhs, prhs);
00084 view.data(nlhs, plhs, 0, 0);
00085
00086
00087 if (nrhs % 2 != 0 && mxIsStruct(plhs[0])) {
00088 mxArray *temp = 0;
00089 if (mxGetNumberOfFields(plhs[0]) == 1) {
00090 temp = mxDuplicateArray(mxGetFieldByNumber(plhs[0], 0, 0));
00091 } else {
00092 temp = mxCreateStructMatrix(0, 0, 0, 0);
00093 }
00094 mxDestroyArray(plhs[0]);
00095 plhs[0] = temp;
00096 }
00097 }
00098
00099 mxArray *Bag::getFileName() const
00100 {
00101 return mxCreateString(::rosbag::Bag::getFileName().c_str());
00102 }
00103
00104 mxArray *Bag::getMode() const
00105 {
00106 mxArray *result = mxCreateNumericMatrix(1, 1, mxUINT8_CLASS, mxREAL);
00107 *static_cast<uint8_T *>(mxGetData(result)) = static_cast<uint8_T>(::rosbag::Bag::getMode());
00108 return result;
00109 }
00110
00111 mxArray *Bag::getMajorVersion() const
00112 {
00113 mxArray *result = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
00114 *static_cast<uint32_T *>(mxGetData(result)) = static_cast<uint32_T>(::rosbag::Bag::getMajorVersion());
00115 return result;
00116 }
00117
00118 mxArray *Bag::getMinorVersion() const
00119 {
00120 mxArray *result = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
00121 *static_cast<uint32_T *>(mxGetData(result)) = static_cast<uint32_T>(::rosbag::Bag::getMinorVersion());
00122 return result;
00123 }
00124
00125 mxArray *Bag::getSize() const
00126 {
00127 mxArray *result = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
00128 *static_cast<uint64_T *>(mxGetData(result)) = static_cast<uint64_T>(::rosbag::Bag::getSize());
00129 return result;
00130 }
00131
00132 void Bag::setCompression(int nrhs, const mxArray *prhs[])
00133 {
00134 if (nrhs < 1) throw ArgumentException("Bag.setCompression", 1);
00135 int value = Options::getIntegerScalar(prhs[0]);
00136 if (value < 0 || value > ::rosbag::compression::BZ2) throw Exception("Bag.setCompression", "Invalid value for property Compression");
00137 ::rosbag::compression::CompressionType compression = static_cast< ::rosbag::compression::CompressionType >(Options::getIntegerScalar(prhs[0]));
00138 ::rosbag::Bag::setCompression(compression);
00139 }
00140
00141 mxArray *Bag::getCompression() const
00142 {
00143 mxArray *result = mxCreateNumericMatrix(1, 1, mxUINT8_CLASS, mxREAL);
00144 *static_cast<uint8_T *>(mxGetData(result)) = static_cast<uint8_T>(::rosbag::Bag::getCompression());
00145 return result;
00146 }
00147
00148 void Bag::setChunkThreshold(int nrhs, const mxArray *prhs[])
00149 {
00150 if (nrhs < 1) throw ArgumentException("Bag.setChunkThreshold", 1);
00151 uint32_t chunkThreshold = static_cast<uint32_t>(Options::getIntegerScalar(prhs[0]));
00152 ::rosbag::Bag::setChunkThreshold(chunkThreshold);
00153 }
00154
00155 mxArray *Bag::getChunkThreshold() const
00156 {
00157 mxArray *result = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
00158 *static_cast<uint32_T *>(mxGetData(result)) = static_cast<uint32_T>(::rosbag::Bag::getChunkThreshold());
00159 return result;
00160 }
00161
00162 void Bag::write(int nrhs, const mxArray *prhs[])
00163 {
00164 if (nrhs < 3) throw ArgumentException("Bag.write", 3);
00165
00166
00167 std::string topic = Options::getString(prhs[0]);
00168 std::string datatype = Options::getString(prhs[1]);
00169 const mxArray *data = prhs[2];
00170 ConnectionHeader connection_header;
00171 ros::Time timestamp;
00172 for(int i = 3; i < nrhs; ++i) {
00173 if (mxIsStruct(prhs[i])) {
00174 if (!connection_header.fromMatlab(prhs[i])) throw Exception("Bag.write", "failed to parse connection header");
00175 continue;
00176 }
00177
00178 if (Options::isDoubleScalar(prhs[i])) {
00179 timestamp = ros::Time(Options::getDoubleScalar(prhs[i]));
00180 continue;
00181 }
00182 }
00183
00184
00185 if (timestamp.isZero()) timestamp = ros::Time::now();
00186
00187
00188 MessagePtr introspection = cpp_introspection::messageByDataType(datatype);
00189 if (!introspection) throw Exception("Bag.write", "unknown datatype '" + datatype + "'");
00190 Conversion conversion(introspection);
00191
00192
00193 std::size_t count = conversion.numberOfInstances(data);
00194 for(std::size_t i = 0; i < count; ++i) {
00195 MessagePtr message = Conversion(introspection).fromMatlab(data, i);
00196 if (!message) throw Exception("Bag.write", "failed to parse message of type " + datatype);
00197
00198 ::rosbag::Bag::write(topic, timestamp, *message, connection_header);
00199 }
00200 }
00201
00202 }
00203 }