Exemplo n.º 1
0
boost::optional<protobuf::ExperimentMetadataMsg::MetadataStruct> Experiment::read_metadata(ProjectHandlerErrorCode& err_out) {
  if (!meta_file_input_stream_) {
    err_out = ProjectHandlerErrorCode::IO_ERROR;
    return boost::none;
  }

  if (fseek(meta_file_handler_, 0, SEEK_SET) != 0) {  // Set to start of file
    err_out = ProjectHandlerErrorCode::IO_ERROR;
    return boost::none;
  }
  io::CodedInputStream coded_input_stream(meta_file_input_stream_);
  uint32_t msg_size;
  bool result = coded_input_stream.ReadVarint32(&msg_size); //If false, => end of file
  protobuf::ExperimentMetadataMsg::MetadataStruct read_msg;
  if (result) {
    io::CodedInputStream::Limit msg_limit = coded_input_stream.PushLimit(msg_size);
    if (read_msg.ParseFromCodedStream(&coded_input_stream)) {
      coded_input_stream.PopLimit(msg_limit);
      err_out = ProjectHandlerErrorCode::SUCCESS;
      return read_msg;
    } else {
      err_out = ProjectHandlerErrorCode::IO_ERROR;
      return boost::none;
    }
  } else {
    err_out = ProjectHandlerErrorCode::END_OF_FILE;
    return boost::none;
  }
}
Exemplo n.º 2
0
/*
 * The metadata contains information about what sensors sensordata is stored in the given experiment.
 * The metadata also contains notes about the experiment that could identify the experiment later on.
 *
 * ExperimentMetadataStruct are written instead of GeneralMsg to avoid writing experiment name to file.
 * Writing GeneralMsg could be problematic when e.g. renaming because you then have to edit the binary data
 * that the medatada contains to the new name.
 */
ProjectHandlerErrorCode Experiment::write_metadata(const std::vector<std::string>& tags, const boost::optional<std::string>& notes) {
  if (fseek(meta_file_handler_, 0, SEEK_SET) != 0) {
    std::cout << "Could not fseek file" << std::endl;
    return ProjectHandlerErrorCode::IO_ERROR;
  } else {
    if (!meta_file_handler_) {
      std::cout << "!!meta_file_handler" << std::endl;
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    protobuf::ExperimentMetadataMsg::MetadataStruct read_msg;
    protobuf::ExperimentMetadataMsg::MetadataStruct new_msg;
    io::CodedInputStream coded_input_stream(meta_file_input_stream_);
    uint32_t msg_size;
    bool read_result = coded_input_stream.ReadVarint32(&msg_size);
    if (read_result) {
      // If there's old metadata, read it and copy sensor_configurations only, discard other old metadata information.
      io::CodedInputStream::Limit msg_limit = coded_input_stream.PushLimit(msg_size);
      if (read_msg.ParseFromCodedStream(&coded_input_stream)) {
        coded_input_stream.PopLimit(msg_limit);
        // Copy sensor configurations
        google::protobuf::RepeatedPtrField< ::protobuf::SensorConfiguration > sensor_configurations = read_msg.sensor_configurations();
        // If there were to be no sensor_configurations absent. The RepeatedField should be empty thus not adding any configurations.
        for (auto&  sensor_config : sensor_configurations ) {
          protobuf::SensorConfiguration* sensor_configuration =
              new_msg.add_sensor_configurations();
          sensor_configuration->CopyFrom(sensor_config);
        }
      }
    }

    for (auto& tag : tags) {
      new_msg.add_tags(tag);
    }
    if (notes) {
      new_msg.set_notes(notes.get());
    }

    if (!::ftruncate(::fileno(meta_file_handler_), 0)) {  // empty file
      std::cout << "Could not empty file" << std::endl;
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    bool write_result;
    {
      io::FileOutputStream file_output_stream(::fileno(meta_file_handler_));
      io::CodedOutputStream coded_output_stream(&file_output_stream);
      coded_output_stream.WriteVarint32(new_msg.ByteSize());
      write_result = new_msg.SerializeToCodedStream(&coded_output_stream);
    }
    if (fflush(meta_file_handler_)) {
      std::cout << "Could not flush file" << std::endl;
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    if (write_result) {
      return ProjectHandlerErrorCode::SUCCESS;
    } else {
      std::cout << "No write result" << std::endl;
      return ProjectHandlerErrorCode::IO_ERROR;
    }
  }
}
Exemplo n.º 3
0
/*
 * Experiment::read_protobuf_data(ProjectHandlerErrorCode& err_out)
 *
 * If it's possible to read the varin32, then there's probably data in the stream.
 * Because it's cheap to create and destroy google io streams, the codedinputstream
 * is declared locally. The varin32 that was previously read contains information about
 * how many bytes the stored binary message contains. You then have to
 * push the streams "start pointer"(limit) to then try to read the binary data until
 * that pointer and then try to parse the data. If the parsed data is valid you have to
 * pop the limit back to it's previous point. After the function goes out of scope
 * the io stream is destructed and when the function is called once again, the data will be
 * at the start of the new io stream.
 */
boost::optional<protobuf::GeneralMsg> Experiment::read_protobuf_data(ProjectHandlerErrorCode& err_out) {

  if (open_mode_ == experiment_open_mode::read) {
    if (!data_file_input_stream_) {
      err_out = ProjectHandlerErrorCode::IO_ERROR;
      return boost::none;
    }

    io::CodedInputStream coded_input_stream(data_file_input_stream_);
    uint32_t msg_size;
    bool result = coded_input_stream.ReadVarint32(&msg_size);
    protobuf::GeneralMsg read_msg;

    if (result) {
      io::CodedInputStream::Limit msg_limit = coded_input_stream.PushLimit(msg_size);
      if (read_msg.ParseFromCodedStream(&coded_input_stream)) {
        coded_input_stream.PopLimit(msg_limit);
      } else {
        err_out = ProjectHandlerErrorCode::IO_ERROR;
        return boost::none;
      }
    } else {
        err_out = ProjectHandlerErrorCode::END_OF_FILE;
        return boost::none;
    }
    err_out = ProjectHandlerErrorCode::SUCCESS;
    return read_msg;
  } else {
    err_out = ProjectHandlerErrorCode::IO_ERROR;
    return boost::none;
  }
}
TEST_F(PluginCompatibilityTest, PreBourbaki) {
  // Read the entire hex data.
  std::fstream file = std::fstream(
      SOLUTION_DIR / "ksp_plugin_test" / "pre_bourbaki.proto.hex");
  CHECK(file.good());
  std::string hex;
  while (!file.eof()) {
    std::string line;
    std::getline(file, line);
    for (auto const c : line) {
      if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
        hex.append(1, c);
      }
    }
  }
  file.close();

  // Parse it and convert to binary data.
  UniqueBytes bin(hex.size() / 2);
  HexadecimalDecode(Array<std::uint8_t const>(
                        reinterpret_cast<const std::uint8_t*>(hex.c_str()),
                        hex.size()),
                    bin.get());

  // Construct a protocol buffer from the binary data.
  google::protobuf::io::CodedInputStream coded_input_stream(
      bin.data.get(), static_cast<int>(bin.size));
  serialization::Plugin pre_bourbaki_serialized_plugin;
  CHECK(pre_bourbaki_serialized_plugin.MergeFromCodedStream(
            &coded_input_stream));

  // Construct a plugin from the protocol buffer.
  auto plugin = TestablePlugin::ReadFromMessage(pre_bourbaki_serialized_plugin);

  // Do some operations on the plugin.
  plugin->KeepAllVessels();
  plugin->AdvanceTime(plugin->current_time() + 1 * Second, 2 * Radian);
  plugin->AdvanceTime(plugin->current_time() + 1 * Hour, 3 * Radian);

  // Serialize and deserialize it in the new format.
  serialization::Plugin post_bourbaki_serialized_plugin;
  plugin->WriteToMessage(&post_bourbaki_serialized_plugin);
  plugin = TestablePlugin::ReadFromMessage(post_bourbaki_serialized_plugin);
}
Exemplo n.º 5
0
/*
 * If, for some reason, you would like to be on the safe side and write all, for the time of writing,
 * known sensors to the metadata struct, this is the function to be called.
 *
 */
ProjectHandlerErrorCode Experiment::write_all_sensor_configurations_to_metadata() {
  if (fseek(meta_file_handler_, 0, SEEK_SET) != 0) {
    return ProjectHandlerErrorCode::IO_ERROR;
  } else {
    if (!meta_file_handler_) {
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    protobuf::ExperimentMetadataMsg::MetadataStruct read_msg;
    protobuf::ExperimentMetadataMsg::MetadataStruct new_msg;
    io::CodedInputStream coded_input_stream(meta_file_input_stream_);
    uint32_t msg_size;
    bool read_result = coded_input_stream.ReadVarint32(&msg_size);
    if (read_result) {
      //If there's old metadata, read it and copy meta_daata only, discard other old sensor_configuration information.
      io::CodedInputStream::Limit msg_limit = coded_input_stream.PushLimit(msg_size);
      if (read_msg.ParseFromCodedStream(&coded_input_stream)) {
        coded_input_stream.PopLimit(msg_limit);
        google::protobuf::RepeatedPtrField< ::std::string> tags = read_msg.tags();
        for (auto& tag : tags) {
          new_msg.add_tags(tag);
        }
        if (read_msg.has_notes()) {
          new_msg.set_notes(read_msg.notes());
        }
      }
    }
    {
      protobuf::SensorConfiguration* sensor_configuration =
         new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(0);
      sensor_configuration->set_name("imucam");
      std::vector<std::string> v = {"accX","accY","accZ","gyrX","gyrY","gyrZ","magX","magY","magZ","roll","pitch","yaw"};
      sensor_configuration->set_max_attributes(v.size());
      int i = 0;
      for (auto& s : v) {
        protobuf::AttributeConfiguration* attribute_configuration =
         sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(i);
        attribute_configuration->set_name(s);
        i++;
      }
    }
    {
      protobuf::SensorConfiguration* sensor_configuration =
         new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(1);
      sensor_configuration->set_name("imucar");
      std::vector<std::string> v = {"accX","accY","accZ","gyrX","gyrY","gyrZ","magX","magY","magZ","roll","pitch","yaw"};
      sensor_configuration->set_max_attributes(v.size());
      int i = 0;
      for (auto& s : v) {
        protobuf::AttributeConfiguration* attribute_configuration =
         sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(i);
        attribute_configuration->set_name(s);
        i++;
      }
    }
    {
      protobuf::SensorConfiguration* sensor_configuration =
         new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(2);
      sensor_configuration->set_name("carcan1");
      std::vector<std::string> v = {"CAN_ID", "CAN_message_length"};
      sensor_configuration->set_max_attributes(v.size());
      int i = 0;
      for (auto& s : v) {
        protobuf::AttributeConfiguration* attribute_configuration =
         sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(i);
        attribute_configuration->set_name(s);
        i++;
      }
    }
    {
      protobuf::SensorConfiguration* sensor_configuration =
       new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(3);
      sensor_configuration->set_name("can");
      std::vector<std::string> v = {"CAN_ID", "CAN_message_length"};
      sensor_configuration->set_max_attributes(v.size());
      int i = 0;
      for (auto& s : v) {
        protobuf::AttributeConfiguration* attribute_configuration =
         sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(i);
        attribute_configuration->set_name(s);
        i++;
      }
    }
    {
      protobuf::SensorConfiguration* sensor_configuration =
       new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(4);
      sensor_configuration->set_name("gps");
      std::vector<std::string> v = {"UT-Time", "Lat", "Lon", "Speed(m/s)", "Course/Heading"};
      sensor_configuration->set_max_attributes(v.size());
      int i = 0;
      for (auto& s : v) {
        protobuf::AttributeConfiguration* attribute_configuration =
         sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(i);
        attribute_configuration->set_name(s);
        i++;
      }
    }
    {
      protobuf::SensorConfiguration* sensor_configuration =
       new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(30);
      sensor_configuration->set_name("corrsys");
      std::vector<std::string> v = {"abstime","starttime","h1","h2","h3","hc1","hc2","hc3","pitch","roll",
          "roll2","pitchrate","rollrate","roll2rate","vabs","vlat","vtrans","slipangle"};
      sensor_configuration->set_max_attributes(v.size());
      int i = 0;
      for (auto& s : v) {
        protobuf::AttributeConfiguration* attribute_configuration =
         sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(i);
        attribute_configuration->set_name(s);
        i++;
      }
    }
    if (::ftruncate(::fileno(meta_file_handler_), 0)) {  // empty file
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    bool write_result;
    {
      io::FileOutputStream file_output_stream(::fileno(meta_file_handler_));
      io::CodedOutputStream coded_output_stream(&file_output_stream);
      coded_output_stream.WriteVarint32(new_msg.ByteSize());
      write_result = new_msg.SerializeToCodedStream(&coded_output_stream);
    }
    if (fflush(meta_file_handler_)) {
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    if (write_result) {
      return ProjectHandlerErrorCode::SUCCESS;
    } else {
      return ProjectHandlerErrorCode::IO_ERROR;
    }
  }
  return ProjectHandlerErrorCode::SUCCESS;
}
Exemplo n.º 6
0
/*
 * The metadata should contain data of which sensors were present during
 * a given data collection. This is so that the client should know which
 * sensors the user could choose to get before a playback of the collection.
 *
 * The function simply updates the MetadataStruct in the metadata message
 * in the metadata file(.meta)
 */
ProjectHandlerErrorCode Experiment::write_sensor_configuration_metadata(const std::vector<boost::shared_ptr<AbstractSensor>>& sensors) {
  if (fseek(meta_file_handler_, 0, SEEK_SET) != 0) {
    return ProjectHandlerErrorCode::IO_ERROR;
  } else {
    if (!meta_file_handler_) {
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    protobuf::ExperimentMetadataMsg::MetadataStruct read_msg;
    protobuf::ExperimentMetadataMsg::MetadataStruct new_msg;
    io::CodedInputStream coded_input_stream(meta_file_input_stream_);
    uint32_t msg_size;
    bool read_result = coded_input_stream.ReadVarint32(&msg_size);
    if (read_result) {
      //If there's old metadata, read it and copy meta_daata only, discard other old sensor_configuration information.
      io::CodedInputStream::Limit msg_limit = coded_input_stream.PushLimit(msg_size);
      if (read_msg.ParseFromCodedStream(&coded_input_stream)) {
        coded_input_stream.PopLimit(msg_limit);
        google::protobuf::RepeatedPtrField< ::std::string> tags = read_msg.tags();
        for (auto& tag : tags) {
          new_msg.add_tags(tag);
        }
        if (read_msg.has_notes()) {
          new_msg.set_notes(read_msg.notes());
        }
      }
    }

    std::map<int,std::string> attribute_names;
    for (auto& sensor : sensors) {
      protobuf::SensorConfiguration* sensor_configuration =
          new_msg.add_sensor_configurations();
      sensor_configuration->set_sensor_id(sensor->get_id());
      sensor_configuration->set_name(sensor->get_name());
      sensor_configuration->set_max_attributes(sensor->get_max_attributes());

      auto iterators = sensor->get_attribute_iterators();
      for (auto itr = iterators.first; itr != iterators.second; ++itr) {
        protobuf::AttributeConfiguration* attribute_configuration =
            sensor_configuration->add_attribute_configurations();
        attribute_configuration->set_index(itr->first);
        attribute_configuration->set_name(itr->second.attr_name);
        attribute_names.insert(std::pair<int,std::string>(itr->first, itr->second.attr_name));
      }
    }
    if (::ftruncate(::fileno(meta_file_handler_), 0)) {  // empty file
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    bool write_result;
    {
      io::FileOutputStream file_output_stream(::fileno(meta_file_handler_));
      io::CodedOutputStream coded_output_stream(&file_output_stream);
      coded_output_stream.WriteVarint32(new_msg.ByteSize());
      write_result = new_msg.SerializeToCodedStream(&coded_output_stream);
    }
    if (fflush(meta_file_handler_)) {
      return ProjectHandlerErrorCode::IO_ERROR;
    }
    if (write_result) {
      std::string text_file_header("time, ID");
      for (auto& attr : attribute_names) {
        text_file_header.append(", " + attr.second);
      }
      return write_text_data(text_file_header);
    } 
    else {
      return ProjectHandlerErrorCode::IO_ERROR;
    }
  }
}