예제 #1
0
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;
    return 1;
  }

  std::map<std::string, Vehicle> vehicles;

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

    IMC::Message* msg = NULL;

    uint16_t curr_rpm = 0;

    bool got_state = false;
    IMC::EstimatedState estate;
    double last_lat;
    double last_lon;

    // Accumulated travelled distance
    double distance = 0.0;
    // Accumulated travelled time
    double duration = 0.0;

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

    bool ignore = false;
    uint16_t sys_id = 0xffff;
    std::string sys_name;

    try
    {
      while ((msg = IMC::Packet::deserialize(*is)) != 0)
      {
        if (msg->getId() == DUNE_IMC_ANNOUNCE)
        {
          IMC::Announce* ptr = static_cast<IMC::Announce*>(msg);
          if (sys_id == ptr->getSource())
          {
            sys_name = ptr->sys_name;
          }
        }
        else if (msg->getId() == DUNE_IMC_LOGGINGCONTROL)
        {
          if (!got_name)
          {
            IMC::LoggingControl* ptr = static_cast<IMC::LoggingControl*>(msg);

            if (ptr->op == IMC::LoggingControl::COP_STARTED)
            {
              sys_id = ptr->getSource();
              log_name = ptr->name;
              got_name = true;
            }
          }
        }
        else if (msg->getId() == DUNE_IMC_ESTIMATEDSTATE)
        {
          if (msg->getTimeStamp() - estate.getTimeStamp() > c_timestep)
          {
            IMC::EstimatedState* ptr = static_cast<IMC::EstimatedState*>(msg);

            if (!got_state)
            {
              estate = *ptr;
              Coordinates::toWGS84(*ptr, last_lat, last_lon);

              got_state = true;
            }
            else if (curr_rpm > c_min_rpm)
            {
              double lat, lon;
              Coordinates::toWGS84(*ptr, lat, lon);

              double dist = Coordinates::WGS84::distance(last_lat, last_lon, 0.0,
                                                         lat, lon, 0.0);

              // Not faster than maximum considered speed
              if (dist / (ptr->getTimeStamp() - estate.getTimeStamp()) < c_max_speed)
              {
                distance += dist;
                duration += msg->getTimeStamp() - estate.getTimeStamp();
              }

              estate = *ptr;
              last_lat = lat;
              last_lon = lon;
            }
          }
        }
        else if (msg->getId() == DUNE_IMC_RPM)
        {
          IMC::Rpm* ptr = static_cast<IMC::Rpm*>(msg);
          curr_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;

        // ignore idles
        // either has the string _idle or has only the time.
        if (log_name.find("_idle") != std::string::npos ||
            log_name.size() == 15)
        {
          ignore = true;
          std::cerr << "this is an idle log";
          break;
        }
      }
    }
    catch (std::runtime_error& e)
    {
      std::cerr << "ERROR: " << e.what() << std::endl;
    }

    delete is;

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

    if (distance > 0)
    {
      vehicles[sys_name].duration += duration;
      vehicles[sys_name].distance += distance;
      vehicles[sys_name].logs.push_back(Log(log_name, distance, duration));
    }
  }

  double total_distance = 0;
  double total_duration = 0;

  std::map<std::string, Vehicle>::const_iterator itr = vehicles.begin();
  for (; itr != vehicles.end(); ++itr)
  {
    std::cout << std::endl;
    std::cout << "## " << itr->first << std::endl << std::endl;
    std::cout << "* Distance travelled per plan (m):" << std::endl;

    for (size_t i = 0; i < itr->second.logs.size(); ++i)
    {
      std::cout << " - "
                << itr->second.logs[i].distance
                << " in " << String::replace(itr->second.logs[i].name, '_', "\\_")
                << "." << std::endl;
    }

    total_distance += itr->second.distance;
    total_duration += itr->second.duration;

    std::cout << std::endl
              << "* Total travelled distance:" << std::endl
              << " - "
              << std::setprecision(4)
              << std::fixed
              << itr->second.distance / 1000.0 << " km / "
              << (unsigned)itr->second.duration / 60 / 60 << " h "
              << (unsigned)(itr->second.duration / 60) % 60 << " m "
              << (unsigned)itr->second.duration % 60 << " s" << "." << std::endl;
  }

  if (vehicles.size() > 1)
  {
    std::cout << std::endl
              << "## Summary" << std::endl
              << " - Total distance: "
              << std::setprecision(2)
              << std::fixed
              << total_distance / 1000.0 << " km" << std::endl
              << " - Total duration: "
              << (unsigned)total_duration / 60 / 60 << " h "
              << (unsigned)(total_duration / 60) % 60 << " m "
              << (unsigned)total_duration % 60 << " s" << std::endl;
  }

  return 0;
}
예제 #2
0
int
main(int32_t argc, char** argv)
{
  if (argc < 2)
  {
    std::cerr << "Usage: " << argv[0] << " <abbrev of imc message 1>,<abbrev of imc message 2>,..,"
              << "<abbrev of imc message n> Data.lsf[.gz] .. Data.lsf[.gz]"
              << std::endl;
    std::cerr << argv[0] << " accepts multiple IMC messages comma separated and "
              << "multiple Data.lsf files space separated." << std::endl;
    std::cerr << "This program does not sort the input Data.lsf files." << std::endl;
    return 1;
  }

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

  IMC::Message* msg;

  uint32_t accum = 0;

  bool done_first = false;

  std::set<uint32_t> ids;
  std::vector<std::string> msgs;
  Utils::String::split(argv[1], ",", msgs);

  for (unsigned k = 0; k < msgs.size(); ++k)
  {
    uint32_t got = IMC::Factory::getIdFromAbbrev(Utils::String::trim(msgs[k]));
    ids.insert(got);
  }

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

    uint32_t i = 0;

    try
    {
      while ((msg = IMC::Packet::deserialize(*is)) != 0)
      {
        if (!done_first)
        {
          // place an empty estimatedstate message in the log
          IMC::EstimatedState state;
          state.setTimeStamp(msg->getTimeStamp());
          IMC::Packet::serialize(&state, buffer);
          lsf.write(buffer.getBufferSigned(), buffer.getSize());
          done_first = true;
        }

        std::set<uint32_t>::const_iterator it;
        it = ids.find(msg->getId());

        if (it != ids.end())
        {
          IMC::Packet::serialize(msg, buffer);
          lsf.write(buffer.getBufferSigned(), buffer.getSize());

          ++i;
        }

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

    std::cerr << i << " messages in " << argv[j] << std::endl;
    accum += i;

    delete is;
  }

  lsf.close();

  std::cerr << "Total of " << accum << " " << argv[1] << " messages." << std::endl;

  return 0;
}
예제 #3
0
int
main(int argc, char** argv)
{
  double speed = 1, begin = 0, end = -1;
  std::map<std::string, bool> filter;
  bool filtering = false;
  int verbose = 0;
  uint16_t src = 0xFFFF, dst = 0xFFFF;

  ++argv; --argc;

  if (!argc)
  {
    usage();
    return 1;
  }

  for (; *argv && **argv == '-'; ++argv, --argc)
  {
    char opt = (*argv)[1];
    ++argv; --argc;

    if (!*argv || **argv == '-')
    {
      std::cerr << "Invalid options\n";
      usage();
      return 1;
    }

    // @todo Use DUNE's OptionParser, too lazy now to do it.
    switch (opt)
    {
      case 'b':
      {
        char* aux;
        begin = std::strtod(*argv, &aux);
        if (*aux != 0 || begin < 0)
        {
          std::cerr << "Invalid begin time: " << *argv << '\n';
          usage();
          return 1;
        }
        break;
      }
      case 'e':
      {
        char* aux;
        end = std::strtod(*argv, &aux);
        if (*aux != 0 || end < 0)
        {
          std::cerr << "Invalid end time: " << *argv << '\n';
          usage();
          return 1;
        }
        break;
      }

      case 'S':
      {
        char* aux;
        src = std::strtol(*argv, &aux, 10);
        if (*aux != 0)
        {
          std::cerr << "Invalid source address: " << *argv << '\n';
          usage();
          return 1;
        }
        break;
      }
      case 'D':
      {
        char* aux;
        dst = std::strtol(*argv, &aux, 10);
        if (*aux != 0)
        {
          std::cerr << "Invalid destination adress: " << *argv << '\n';
          usage();
          return 1;
        }
        break;
      }
      case 's':
      {
        char* aux;
        speed = std::strtod(*argv, &aux);
        if (*aux != 0 || speed < 0)
        {
          std::cerr << "Invalid speed setting: " << *argv << '\n';
          usage();
          return 1;
        }
        break;
      }
      case 'v':
        verbose = std::atoi(*argv);
        break;
      case 'm':
      {
        std::vector<std::string> list;
        DUNE::Utils::String::split(*argv, ",", list);
        for (uint16_t i = 0; i < list.size(); ++i)
          filter[list[i]] = true;
        filtering = true;
      }
      break;
      default:
        std::cerr << "Invalid option: '-" << opt << "\'\n";
        usage();
        return 1;
    }
  }

  if (argc < 3)
  {
    std::cerr << "Invalid arguments" << std::endl;
    usage();
    return 1;
  }

  if (begin > 0 && end > 0 && begin > end)
  {
    std::cerr << "Invalid time offsets" << std::endl;
    usage();
    return 1;
  }

  UDPSocket sock;
  Address dest(argv[0]);
  uint16_t port = std::atoi(argv[1]);

  argv += 2;

  std::cout << std::fixed << std::setprecision(4);

  for (; *argv != 0; argv++)
  {
    Path file(*argv);
    std::istream* is;

    if (file.isDirectory())
    {
      file = file / "Data.lsf";
      if (!file.isFile())
        file += ".gz";
    }

    if (!file.isFile())
    {
      std::cerr << file << " does not exist\n";
      return 1;
    }

    Compression::Methods method = Compression::Factory::detect(file.c_str());
    if (method == METHOD_UNKNOWN)
      is = new std::ifstream(file.c_str(), std::ios::binary);
    else
      is = new Compression::FileInput(file.c_str(), method);

    IMC::Message* m;

    m = IMC::Packet::deserialize(*is);
    if (!m)
    {
      std::cerr << file << " contains no messages\n";
      delete is;
      continue;
    }

    DUNE::Utils::ByteBuffer bb;

    double time_origin = m->getTimeStamp();
    if (begin >= 0)
    {
      do
      {
        if (m->getTimeStamp() - time_origin >= begin)
          break;
        delete m;
        m = IMC::Packet::deserialize(*is);
      }
      while (m);

      if (!m)
      {
        std::cerr << "no messages for specified time range" << std::endl;
        return 1;
      }
    }
    else
      begin = 0;

    double start_time = Clock::getSinceEpoch();
    double now = start_time;

    do
    {
      double msg_ts = m->getTimeStamp();
      double vtime = msg_ts - time_origin;

      m->setTimeStamp(start_time + vtime);

      double future = 0;

      if (speed > 0 && vtime >= begin)
      {
        // Delay time to mimic behavior at specified speed
        future = start_time + vtime / speed - begin;
        double delay_time = (future - now);
        if (delay_time > 0)
          Delay::wait(delay_time);
      }
      now = Clock::getSinceEpoch();

      if (vtime >= begin
          && (src == 0xFFFF || src == m->getSource())
          && (dst == 0xFFFF || dst == m->getDestination())
          && (!filtering || filter[m->getName()]))
      {
        // Send message
        IMC::Packet::serialize(m, bb);
        sock.write(bb.getBuffer(), m->getSerializationSize(), dest, port);
        if (verbose >= 1)
          std::cout << (begin + now - start_time) << ' ' << vtime << ' ' << now - future << " : " << m->getName() << '\n';
        if (verbose >= 2)
          m->toText(std::cout);
      }

      delete m;

      if (end >= 0 && vtime >= end)
        break;
    }
    while ((m = IMC::Packet::deserialize(*is)) != 0);
    delete is;
  }
  return 0;
}
예제 #4
0
int
main(int argc, char** argv)
{
    Utils::OptionParser options;
    options.executable(argv[0])
    .program(argv[0])
    .copyright(DUNE_COPYRIGHT)
    .email(DUNE_CONTACT)
    .version("1.0")
    .date(DUNE_BUILD_TIME)
    .arch(DUNE_SYSTEM_NAME)
    .add("-t", "--timeout",
         "Interval to ignore data right after a new device has been turned on."
         " Default is 10.0", "TIMEOUT")
    .add("-f", "--file",
         "Log file in .lsf or .lsf.gz format", "FILE");

    // Parse command line arguments.
    if (!options.parse(argc, argv) || options.value("--file").empty())
    {
        if (options.bad())
            std::cerr << "ERROR: " << options.error() << std::endl;

        options.usage();
        return 1;
    }

    std::string file = options.value("--file");

    std::istream* is = 0;
    Compression::Methods method = Compression::Factory::detect(file.c_str());
    if (method == METHOD_UNKNOWN)
        is = new std::ifstream(file.c_str(), std::ios::binary);
    else
        is = new Compression::FileInput(file.c_str(), method);

    IMC::Message* msg = NULL;

    // Current and voltage measurements
    ElectricMeasure current_measures[SU_COUNT];
    ElectricMeasure voltage_measures[SU_COUNT];

    typedef std::map<uint8_t, std::string> Id2Name;
    Id2Name channel_names;

    typedef std::map<uint8_t, uint8_t> Supply2Id;
    Supply2Id measure_ids;

    typedef std::map<std::string, double> Name2Power;
    Name2Power device_power;

    // Got all power channels
    bool got_channels = false;

    // Time counter
    double counter = 0.0;

    // Test has started
    bool test_started = false;

    // Ignore measures if true
    bool ignore_data = true;
    bool was_ignoring = true;

    // Last timestamp
    double last_timestamp = -1.0;

    // Timeout for ignoring data
    double ignore_timeout;
    if (options.value("--timeout").empty())
        ignore_timeout = 10.0;
    else
        ignore_timeout = atoi(options.value("--timeout").c_str());

    // Last device turned on
    Id2Name::const_iterator last_device = channel_names.end();

    try
    {
        while ((msg = IMC::Packet::deserialize(*is)) != 0)
        {
            if (last_timestamp < 0.0)
                last_timestamp = msg->getTimeStamp();

            if (ignore_data != was_ignoring)
            {
                if (!was_ignoring)
                {
                    // reset timer counter
                    counter = 0.0;
                }
            }

            if (ignore_data && test_started)
            {
                counter += msg->getTimeStamp() - last_timestamp;

                if (counter >= ignore_timeout)
                {
                    counter = 0.0;
                    ignore_data = false;
                }
            }

            was_ignoring = ignore_data;
            last_timestamp = msg->getTimeStamp();

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

                for (unsigned i = 0; i < SU_COUNT; i++)
                {
                    if (std::strcmp(einfo->label.c_str(), c_supply_name[i].c_str()) == 0)
                    {
                        measure_ids.insert(std::pair<uint8_t, uint8_t>(einfo->id, i));
                        break;
                    }
                }
            }
            else if (msg->getId() == DUNE_IMC_POWERCHANNELCONTROL)
            {
                IMC::PowerChannelControl* pcc = dynamic_cast<IMC::PowerChannelControl*>(msg);

                if (pcc->op == IMC::PowerChannelControl::PCC_OP_TURN_OFF && got_channels)
                {
                    ignore_data = true;
                    test_started = true;
                }
                else if (pcc->op == IMC::PowerChannelControl::PCC_OP_TURN_ON)
                {
                    if (last_device != channel_names.end())
                    {
                        printPower(last_device->second, voltage_measures, current_measures);
                    }
                    else
                    {
                        for (unsigned i = 0; i < SU_COUNT; i++)
                        {
                            voltage_measures[i].update();
                            current_measures[i].update();
                        }
                    }

                    ignore_data = true;
                    last_device = channel_names.find(pcc->id);
                }
            }
            else if (msg->getId() == DUNE_IMC_POWERCHANNELSTATE)
            {
                IMC::PowerChannelState* pcs = dynamic_cast<IMC::PowerChannelState*>(msg);

                if (channel_names.find(pcs->id) == channel_names.end())
                    channel_names.insert(std::pair<uint8_t, std::string>(pcs->id, pcs->label));
                else
                    got_channels = true;
            }
            else if (msg->getId() == DUNE_IMC_VOLTAGE)
            {
                IMC::Voltage* volt = dynamic_cast<IMC::Voltage*>(msg);
                Supply2Id::const_iterator it = measure_ids.find(volt->getSourceEntity());

                if (it != measure_ids.end() && !ignore_data)
                    voltage_measures[it->second].addMeasure(volt->value);
            }
            else if (msg->getId() == DUNE_IMC_CURRENT)
            {
                IMC::Current* curr = dynamic_cast<IMC::Current*>(msg);
                Supply2Id::const_iterator it = measure_ids.find(curr->getSourceEntity());

                if (it != measure_ids.end() && !ignore_data)
                    current_measures[it->second].addMeasure(curr->value);
            }
        }

        // Compute last device in the list
        printPower(last_device->second, voltage_measures, current_measures);
    }
    catch (std::runtime_error& e)
    {
        std::cerr << "ERROR: " << e.what() << std::endl;
    }

    return 0;
}
예제 #5
0
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;
    return 1;
  }

  double total_accum = 0;

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

    IMC::Message* msg = NULL;

    uint16_t curr_rpm = 0;

    bool got_state = false;
    IMC::EstimatedState estate;
    double last_lat;
    double last_lon;

    // Accumulated travelled distance
    double accum = 0;

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

    bool ignore = false;

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

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

            if (ptr->op == IMC::LoggingControl::COP_STARTED)
            {
              log_name = ptr->name;
              got_name = true;
            }
          }
        }
        else if (msg->getId() == DUNE_IMC_ESTIMATEDSTATE)
        {
          if (msg->getTimeStamp() - estate.getTimeStamp() > c_timestep)
          {
            IMC::EstimatedState* ptr = dynamic_cast<IMC::EstimatedState*>(msg);

            if (!got_state)
            {
              estate = *ptr;
              Coordinates::toWGS84(*ptr, last_lat, last_lon);

              got_state = true;
            }
            else if (curr_rpm > c_min_rpm)
            {
              double lat, lon;
              Coordinates::toWGS84(*ptr, lat, lon);

              double dist = Coordinates::WGS84::distance(last_lat, last_lon, 0.0,
                                                         lat, lon, 0.0);

              // Not faster than maximum considered speed
              if (dist / (ptr->getTimeStamp() - estate.getTimeStamp()) < c_max_speed)
                accum += dist;

              estate = *ptr;
              Coordinates::toWGS84(*ptr, last_lat, last_lon);
            }
          }
        }
        else if (msg->getId() == DUNE_IMC_RPM)
        {
          IMC::Rpm* ptr = dynamic_cast<IMC::Rpm*>(msg);
          curr_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;

        // ignore idles
        // either has the string _idle or has only 
        if (log_name.find("_idle") != std::string::npos ||
            log_name.size() == 15)
        {
          ignore = true;
          std::cerr << "this is an idle log";
          break;
        }
      }
    }
    catch (std::runtime_error& e)
    {
      std::cerr << "ERROR: " << e.what() << std::endl;
    }

    delete is;

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

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

    total_accum += accum;
  }

  std::cerr << "Total travelled distance is " << total_accum << "m" << std::endl
            << " or " << total_accum / 1000.0 << " km." << std::endl;

  return 0;
}