int
main(int32_t argc, char** argv)
{
  if (argc <= 1)
  {
    std::cerr << "Usage: " << argv[0] << " <path_to_log_1/Data.lsf[.gz]> ... <path_to_log_n/Data.lsf[.gz]>"
              << std::endl;
    std::cerr << "Or: " << argv[0] << "-e <Voltage Entity Label> <Current Entity Label> <path_to_log_1/Data.lsf[.gz]> ... <path_to_log_n/Data.lsf[.gz]>"
              << std::endl;
    return 1;
  }

  std::string volt_label;
  std::string curr_label;

  unsigned start_index = 1;

  if (strcmp(argv[1], "-e") == 0)
  {
    if (argc < 5)
    {
      std::cerr << "Too few arguments" << std::endl;
      return 1;
    }

    volt_label = argv[2];
    curr_label = argv[3];

    start_index = 4;
  }
  else
  {
    volt_label = c_label;
    curr_label = c_label;
  }

  // Total of energy spent
  double total_accum = 0.0;
  // Total energy spent while the motor was on
  double motor_total_accum = 0.0;

  // Moving average window sizes
  unsigned wsizes[Monitors::FuelLevel::BatteryData::BM_TOTAL];

  for (unsigned k = 0; k < Monitors::FuelLevel::BatteryData::BM_TOTAL; k++)
    wsizes[k] = c_samples;

  for (int32_t i = start_index; i < argc; ++i)
  {
    std::istream* is = 0;
    DUNE::Compression::Methods method = DUNE::Compression::Factory::detect(argv[i]);
    if (method == DUNE::Compression::METHOD_UNKNOWN)
      is = new std::ifstream(argv[i], std::ios::binary);
    else
      is = new DUNE::Compression::FileInput(argv[i], method);

    DUNE::IMC::Message* msg = NULL;

    bool got_name = false;
    std::string log_name = "unknown";

    // Energy computation related data
    Monitors::FuelLevel::BatteryData bdata(wsizes);
    bool volt_entity_set = false;
    bool curr_entity_set = false;
    bool entities_set = false;
    unsigned eids[Monitors::FuelLevel::BatteryData::BM_TOTAL] = {0};
    unsigned samples = 0;
    double last_timestamp = 0.0;
    double accum = 0.0;

    // Current rpm value
    float rpm = 0.0;

    // Ignore some logs
    bool ignore = false;

    try
    {
      while ((msg = DUNE::IMC::Packet::deserialize(*is)) != 0)
      {

        if (msg->getId() == DUNE_IMC_LOGGINGCONTROL)
        {
          if (!got_name)
          {
            DUNE::IMC::LoggingControl* ptr = static_cast<DUNE::IMC::LoggingControl*>(msg);

            if (ptr->op == DUNE::IMC::LoggingControl::COP_STARTED)
            {
              log_name = ptr->name;
              got_name = true;
            }
          }
        }
        else if (msg->getId() == DUNE_IMC_ENTITYINFO)
        {
          DUNE::IMC::EntityInfo* ptr = static_cast<DUNE::IMC::EntityInfo*>(msg);

          if (ptr->label.compare(volt_label) == 0)
          {
            eids[Monitors::FuelLevel::BatteryData::BM_VOLTAGE] = ptr->id;
            volt_entity_set = true;
          }

          if (ptr->label.compare(curr_label) == 0)
          {
            eids[Monitors::FuelLevel::BatteryData::BM_CURRENT] = ptr->id;
            curr_entity_set = true;
          }

          if (!entities_set && volt_entity_set && curr_entity_set)
          {
            bdata.setEntities(eids);
            entities_set = true;
          }
        }
        else if (msg->getId() == DUNE_IMC_VOLTAGE)
        {
          if (entities_set)
          {
            DUNE::IMC::Voltage* ptr = static_cast<DUNE::IMC::Voltage*>(msg);
            bdata.update(ptr);
            ++samples;

            if (samples > c_min_samples)
            {
              float drop = bdata.getEnergyDrop(msg->getTimeStamp() - last_timestamp);
              accum += drop;

              if (rpm > c_min_rpm)
                motor_total_accum += drop;
            }
          }

          last_timestamp = msg->getTimeStamp();
        }
        else if (msg->getId() == DUNE_IMC_CURRENT)
        {
          if (entities_set)
          {
            DUNE::IMC::Current* ptr = static_cast<DUNE::IMC::Current*>(msg);
            bdata.update(ptr);
          }
        }
        else if (msg->getId() == DUNE_IMC_RPM)
        {
          DUNE::IMC::Rpm* ptr = static_cast<DUNE::IMC::Rpm*>(msg);
          rpm = ptr->value;
        }
        else if (msg->getId() == DUNE_IMC_SIMULATEDSTATE)
        {
          // since it has simulated state let us ignore this log
          ignore = true;
          delete msg;
          std::cerr << "this is a simulated log";
          break;
        }

        delete msg;
      }
    }
    catch (std::runtime_error& e)
    {
      std::cerr << "ERROR: " << e.what() << std::endl;
    }

    delete is;

    if (ignore)
    {
      std::cerr << "... ignoring" << std::endl;
      continue;
    }

    std::cerr << "Consumed " << accum << " in " << log_name << "." << std::endl;

    total_accum += accum;
  }

  std::cerr << "Total energy consumed is " << total_accum << "Wh" << std::endl
            << "The amount of " << motor_total_accum
            << std::fixed << std::setprecision(1)
            << "Wh (" << motor_total_accum / total_accum * 100.0
            << "%) was consumed while the motor was on" << std::endl;

  return 0;
}
Пример #2
0
int
main(int32_t argc, char** argv)
{
  if (argc != 3)
  {
    std::cerr << "Usage: " << argv[0] << " <config ini file> <path_to_log.lsf[.gz]>"
              << std::endl;
    return 1;
  }

  Arguments m_args;

  readArgs(argv[1], m_args);
  m_args.filter_args.decay_factor *= 0.01f;

  //! Array of entities
  unsigned m_eids[BatteryData::BM_TOTAL];

  // Filter pointer
  FuelFilter* m_fuel_filter = NULL;

  bool resolved_entities[BatteryData::BM_TOTAL];
  for (unsigned i = 0; i < BatteryData::BM_TOTAL; ++i)
    resolved_entities[i] = false;

  EPMap m_epower;

  bool got_entities = false;

  PseudoTimer timer;
  PeriodicRun pr(1.0);

  ByteBuffer buffer;
  std::ofstream lsf("NewFuel.lsf", std::ios::binary);

  std::istream* is = 0;
  DUNE::Compression::Methods method = DUNE::Compression::Factory::detect(argv[2]);
  if (method == DUNE::Compression::METHOD_UNKNOWN)
    is = new std::ifstream(argv[2], std::ios::binary);
  else
    is = new DUNE::Compression::FileInput(argv[2], method);

  if (!is)
  {
    std::cerr << "bad file" << std::endl;
    return 1;
  }

  is->seekg(0, is->end);
  unsigned file_length = is->tellg();
  is->seekg(0, is->beg);
  Time::Counter<float> prog_timer(5.0);

  DUNE::IMC::Message* msg = NULL;

  DUNE::IMC::FuelLevel* ptr = NULL;

  bool got_first = false;

  try
  {
    while ((msg = DUNE::IMC::Packet::deserialize(*is)) != 0)
    {
      bool log_it = false;

      timer.update(msg->getTimeStamp());

      if (!got_first)
      {
        IMC::EstimatedState state;
        state.setTimeStamp(msg->getTimeStamp());
        IMC::Packet::serialize(&state, buffer);
        lsf.write(buffer.getBufferSigned(), buffer.getSize());
        got_first = true;

        std::cerr << "got first timestamp" << std::endl;

        m_fuel_filter = new FuelFilter(&m_args.filter_args, m_eids, &m_epower,
                                       NULL, true, msg->getTimeStamp());
      }

      if (msg->getId() == DUNE_IMC_ENTITYINFO)
      {
        IMC::EntityInfo* ent = static_cast<IMC::EntityInfo*>(msg);

        if (!got_entities)
        {
          bool got_all = true;

          for (unsigned i = 0; i < BatteryData::BM_TOTAL; ++i)
          {
            if (ent->label == m_args.elb[i])
            {
              m_eids[i] = ent->id;
              resolved_entities[i] = true;
            }

            if (resolved_entities[i] == false)
              got_all = false;
          }

          got_entities = got_all;

          if (got_entities)
            std::cerr << "Got all entities" << std::endl;
        }

        for (unsigned i = 0; i < m_args.est_list.size(); i++)
        {
          if (ent->label == m_args.est_list[i])
            m_epower.insert(EPPair(ent->id, EntityPower(m_args.est_power[i])));
        }

        if (m_args.est_list.size() < m_epower.size())
          std::cerr << "TOO MANY ENTRIES!" << std::endl;

        IMC::Packet::serialize(msg, buffer);
        lsf.write(buffer.getBufferSigned(), buffer.getSize());
        delete msg;
        continue;
      }

      if (msg->getId() == DUNE_IMC_VOLTAGE)
      {
        m_fuel_filter->onVoltage(static_cast<IMC::Voltage*>(msg));
        log_it = true;
      }
      else if (msg->getId() == DUNE_IMC_CURRENT)
      {
        m_fuel_filter->onCurrent(static_cast<IMC::Current*>(msg));
        log_it = true;
      }
      else if (msg->getId() == DUNE_IMC_TEMPERATURE)
      {
        m_fuel_filter->onTemperature(static_cast<IMC::Temperature*>(msg));
        log_it = true;
      }
      else if (msg->getId() == DUNE_IMC_VEHICLESTATE)
      {
        m_fuel_filter->onVehicleState(static_cast<IMC::VehicleState*>(msg));
        log_it = true;
      }
      else if (msg->getId() == DUNE_IMC_FUELLEVEL)
      {
        log_it = true;
      }
      else if (msg->getId() == DUNE_IMC_ENTITYACTIVATIONSTATE)
      {
        m_fuel_filter->onEntityActivationState(static_cast<IMC::EntityActivationState*>(msg));
        log_it = true;
      }

      if (timer.isValid() && pr.doRun(timer.getTime()))
      {
        // Update fuel filter
        if (m_fuel_filter->update())
        {
          IMC::FuelLevel fl;
          fl.setSourceEntity(250);
          fl.setTimeStamp(msg->getTimeStamp());

          m_fuel_filter->fillMessage(fl, m_args.op_labels, m_args.op_values);

          if (ptr != NULL)
          {
            float diff = ptr->value - fl.value;
            char sign = (diff > 0)? '-' : '+';
            if (std::fabs(diff) > 1.0)
              std::cerr << "jumped " << sign
                        << std::fabs(diff) / 100 * m_args.filter_args.full_capacity
                        << " (" << std::fabs(diff) << "%)" << std::endl;
          }

          Memory::clear(ptr);
          ptr = static_cast<IMC::FuelLevel*>(fl.clone());

          IMC::Packet::serialize(&fl, buffer);
          lsf.write(buffer.getBufferSigned(), buffer.getSize());
        }
      }

      if (log_it)
      {
        IMC::Packet::serialize(msg, buffer);
        lsf.write(buffer.getBufferSigned(), buffer.getSize());
      }

      if (prog_timer.overflow())
      {
        std::cerr << (float)is->tellg() / file_length * 100.0 << "%" << std::endl;
        prog_timer.reset();
      }

      delete msg;
    }
  }
  catch (std::runtime_error& e)
  {
    std::cerr << "ERROR: " << e.what() << std::endl;
  }

  Memory::clear(m_fuel_filter);
  Memory::clear(ptr);

  delete is;

  return 0;
}