Ejemplo n.º 1
0
      //! Start a given plan
      //! @param[in] plan_id name of the plan to execute
      //! @param[in] spec plan specification message if any
      //! @param[in] flags plan control flags
      //! @return false if previously executing maneuver was not stopped
      bool
      startPlan(const std::string& plan_id, const IMC::Message* spec, uint16_t flags)
      {
        bool stopped = stopPlan(true);

        changeMode(IMC::PlanControlState::PCS_INITIALIZING,
                   DTR("plan initializing: ") + plan_id);

        if (!loadPlan(plan_id, spec, true))
          return stopped;

        changeLog(plan_id);

        // Flag the plan as starting
        if (initMode() || execMode())
        {
          if (!stopped)
            m_plan->planStopped();

          m_plan->planStarted();
        }

        dispatch(m_spec);

        if ((flags & IMC::PlanControl::FLG_CALIBRATE) &&
            m_args.do_calib)
        {
          if (!startCalibration())
            return stopped;
        }
        else
        {
          IMC::PlanManeuver* pman = m_plan->loadStartManeuver();
          startManeuver(pman);

          if (execMode())
          {
            onSuccess(m_last_event);
          }
          else
          {
            onFailure(m_last_event);
            return stopped;
          }
        }

        return true;
      }
Ejemplo n.º 2
0
      void
      onVehicleManeuver(const IMC::VehicleState* vs)
      {
        if (!execMode() || pendingReply())
          return;

        if (vs->flags & IMC::VehicleState::VFLG_MANEUVER_DONE)
        {
          if (m_plan->isDone())
          {
            vehicleRequest(IMC::VehicleCommand::VC_STOP_MANEUVER);

            std::string comp = DTR("plan completed");
            onSuccess(comp, false);
            m_pcs.last_outcome = IMC::PlanControlState::LPO_SUCCESS;
            m_reply.plan_id = m_spec.plan_id;
            changeMode(IMC::PlanControlState::PCS_READY, comp);
          }
          else
          {
            IMC::PlanManeuver* pman = m_plan->loadNextManeuver();
            startManeuver(pman);
          }
        }
        else
        {
          m_pcs.man_eta = vs->maneuver_eta;
        }
      }
Ejemplo n.º 3
0
      //! Stop current plan being executed
      //! @param[in] plan_startup true if a plan will start right after this stop
      //! @return false if a plan is still running after this
      bool
      stopPlan(bool plan_startup = false)
      {
        if (initMode() || execMode())
        {
          if (!plan_startup)
          {
            // stop maneuver only if we are not executing a plan afterwards
            vehicleRequest(IMC::VehicleCommand::VC_STOP_MANEUVER);

            m_reply.plan_id = m_spec.plan_id;
            m_pcs.last_outcome = IMC::PlanControlState::LPO_FAILURE;
            changeMode(IMC::PlanControlState::PCS_READY, DTR("plan stopped"));
          }
          else
          {
            m_pcs.last_outcome = IMC::PlanControlState::LPO_FAILURE;
            debug("switching to new plan");
            return false;
          }
        }
        else
        {
          if (!plan_startup)
          {
            onFailure(DTR("no plan is running, request ignored"));
            m_reply.plan_id = "";
          }
        }

        return true;
      }
Ejemplo n.º 4
0
      void
      consume(const IMC::VehicleCommand* vc)
      {
        if (vc->type == IMC::VehicleCommand::VC_REQUEST)
          return;

        if ((vc->getDestination() != getSystemId()) ||
            (vc->getDestinationEntity() != getEntityId()) ||
            (m_vreq_ctr != vc->request_id))
          return;

        if (!pendingReply())
          return;

        m_vc_reply_deadline = -1;
        bool error = vc->type == IMC::VehicleCommand::VC_FAILURE;

        // Ignore failure if it failed to stop calibration
        if (error && (vc->command == IMC::VehicleCommand::VC_STOP_CALIBRATION))
        {
          debug("%s", vc->info.c_str());
          error = false;
        }

        if (initMode() || execMode())
        {
          if (error)
            changeMode(IMC::PlanControlState::PCS_READY, vc->info, false);
          return;
        }
      }
Ejemplo n.º 5
0
      //! Report progress
      void
      reportProgress(void)
      {
        // Must be executing or calibrating to be able to compute progress
        if (m_plan == NULL || (!execMode() && !initMode()))
          return;

        m_pcs.plan_progress = m_plan->updateProgress(&m_mcs);
        m_pcs.plan_eta = (int32_t)m_plan->getETA();
      }
Ejemplo n.º 6
0
      //! Change the current plan control state mode
      //! @param[in] s plan control state to switch to
      //! @param[in] event_desc description of the event that motivated the change
      //! @param[in] nid id of the maneuver if any
      //! @param[in] maneuver pointer to maneuver message
      //! @param[in] print true if the messages should be printed to output
      void
      changeMode(IMC::PlanControlState::StateEnum s, const std::string& event_desc,
                 const std::string& nid, const IMC::Message* maneuver, bool print = true)
      {
        double now = Clock::getSinceEpoch();

        if (print)
          war("%s", event_desc.c_str());

        m_last_event = event_desc;

        if (s != m_pcs.state)
        {
          debug(DTR("now in %s state"), DTR(c_state_desc[s]));

          bool was_in_plan = initMode() || execMode();

          m_pcs.state = s;

          bool is_in_plan = initMode() || execMode();

          if (was_in_plan && !is_in_plan)
          {
            m_plan->planStopped();
            changeLog("");
          }
        }

        if (maneuver)
        {
          m_pcs.man_id = nid;
          m_pcs.man_type = maneuver->getId();
        }
        else
        {
          m_pcs.man_id.clear();
          m_pcs.man_type = 0xFFFF;
        }

        m_pcs.setTimeStamp(now);
        dispatch(m_pcs, DF_KEEP_TIME);
      }
Ejemplo n.º 7
0
      //! Get current plan
      void
      getPlan(void)
      {
        if (!initMode() && !execMode())
        {
          onFailure(DTR("no plan is running"));
          return;
        }

        m_reply.arg.set(m_spec);
        m_reply.plan_id = m_spec.plan_id;
        onSuccess();
      }
Ejemplo n.º 8
0
      //! Load a plan into the vehicle
      //! @param[in] plan_id name of the plan
      //! @param[in] arg argument which may either be a maneuver or a plan specification
      //! @param[in] plan_startup true if a plan will start right after
      //! @return true if plan is successfully loaded
      bool
      loadPlan(const std::string& plan_id, const IMC::Message* arg,
               bool plan_startup = false)
      {
        if ((initMode() && !plan_startup) || execMode())
        {
          onFailure(DTR("cannot load plan now"));
          return false;
        }

        std::string info;
        if (!parseArg(plan_id, arg, info))
        {
          changeMode(IMC::PlanControlState::PCS_READY,
                     DTR("plan load failed: ") + info);
          return false;
        }

        IMC::PlanStatistics ps;

        if (!parsePlan(plan_startup, ps))
        {
          changeMode(IMC::PlanControlState::PCS_READY,
                     DTR("plan parse failed: ") + m_reply.info);
          return false;
        }

        // reply with statistics
        m_reply.arg.set(ps);
        m_reply.plan_id = m_spec.plan_id;

        m_pcs.plan_id = m_spec.plan_id;

        onSuccess(DTR("plan loaded"), false);

        return true;
      }
Ejemplo n.º 9
0
      void
      onVehicleError(const IMC::VehicleState* vs)
      {
        std::string err_ents = DTR("vehicle errors: ") + vs->error_ents;
        std::string edesc = vs->last_error_time < 0 ? err_ents : vs->last_error;

        if (execMode())
        {
          onFailure(edesc);
          m_reply.plan_id = m_spec.plan_id;
        }

        // there are new error entities
        if (edesc != m_last_event)
        {
          if (initMode())
          {
            onFailure(edesc);
            m_reply.plan_id = m_spec.plan_id;
          }

          changeMode(IMC::PlanControlState::PCS_BLOCKED, edesc, false);
        }
      }
Ejemplo n.º 10
0
int main(){
  pid_t pid, sid;
  int       list_s;                /*  listening socket          */
  int       conn_s;                /*  connection socket         */
  short int port = 1995;                  /*  port number               */
  struct    sockaddr_in servaddr;  /*  socket address structure  */
  int i;
  uint8_t numClients = 0;
  threadInfo* info;

  /* Fork off the parent process */
  pid = fork();
  if(pid < 0) {
    exit(EXIT_FAILURE);
  }

  /* If we got a good PID, then we can exit the parent process */
  if(pid > 0){
    exit(EXIT_SUCCESS);
  }

  umask(0);

  printf("Daemon started.  Writing all further notices to daemon log: /var/log/daemon.log\n");

  // Enable Signal Handler
  signal(SIGTERM, catch_term);

  /* Open Log File Here */
  openlog("SEASSERVER",LOG_PID,LOG_DAEMON);
  syslog(LOG_DAEMON|LOG_INFO,"Daemon Started.");

  /* Open Config File Here */
  if(!readConfig()){
    syslog(LOG_DAEMON|LOG_ERR,"Unable to Read Configuration File.  Daemon Terminated.\n");
    exit(EXIT_FAILURE);
  }

  /* Create a new SID for the child process */
  sid = setsid();
  if(sid < 0){
    syslog(LOG_DAEMON|LOG_ERR,"Unable to create a new SID for child process. Daemon Terminated.");
    exit(EXIT_FAILURE);
  }

  /* Change the current working directory */
  if((chdir("/")) < 0){
    syslog(LOG_DAEMON|LOG_ERR,"Unable to switch working directory. Daemon Terminated.");
    exit(EXIT_FAILURE);
  }

  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);

  /* Setup TCP/IP Socket */
  if((list_s = socket(AF_INET, SOCK_STREAM, 0)) < 0){
      syslog(LOG_DAEMON|LOG_ERR,"Unable to create socket. Daemon Terminated.");
      exit(EXIT_FAILURE);
  }

  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servaddr.sin_port = htons(port);

#ifdef DEBUG
  syslog(LOG_DAEMON|LOG_INFO,"Opening Spectrometers.");
#endif
  // Power Cycle GPIO for USB Hub to make sure USB ports initialized correctly
  //system("echo 0 > /sys/class/gpio/gpio168/value");
  //sleep(3);
  //system("echo 1 > /sys/class/gpio/gpio168/value");
  //sleep(3);
  // Connect the USB Spectrometers
  char *serialNumbers[NUM_SPECS] = {getSerialNumber(0),getSerialNumber(1)};
  if(connectSpectrometers(serialNumbers) == CONNECT_ERR)
  {
      syslog(LOG_DAEMON|LOG_ERR,"Spectrometers could not be opened.  Daemon Exiting");
      exit(EXIT_FAILURE);
  }
#ifdef DEBUG
  syslog(LOG_DAEMON|LOG_INFO,"Spectrometers Opened.");
#endif

  applyConfig();
  logConfig();

  // Start LON Dispatch
  syslog(LOG_DAEMON|LOG_INFO,"Starting LON Connection.");
  if(startDispatch(LONPORT) == -1){
      syslog(LOG_DAEMON|LOG_ERR,"LON Not Connected!  Check serial port.");
      exit(EXIT_FAILURE);
  } else {
    syslog(LOG_DAEMON|LOG_INFO,"LON Connection Started.");
  }

  // Init Bench Config and Power Management GPIOs (See SEASPeriperalCommands.c)
  readBenchConfig();
  initPeripherals();

  // Start CTD Sink
  CTDSink* ctdSink = CTDSink::Instance();

  /*  Bind our socket addresss to the
	listening socket, and call listen()  */

  if ( bind(list_s, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ) {
    syslog(LOG_DAEMON|LOG_ERR,"Unable to bind socket. Daemon Terminated.");
    exit(EXIT_FAILURE);
  }

  if ( listen(list_s, NUM_THREADS) < 0 ) {
    syslog(LOG_DAEMON|LOG_ERR,"Unable to listen on socket. Daemon Terminated.");
    exit(EXIT_FAILURE);
  }

  for(i=0; i < NUM_THREADS; i++)
      thread_bin_available[i] = AVAILABLE;

  execMode();

  while(keep_going){
    syslog(LOG_DAEMON|LOG_INFO,"Listening for connection on port %i", port);
    /* Wait for TCP/IP Connection */
    conn_s = accept(list_s, NULL, NULL);
    if ( conn_s < 0 ) {
        syslog(LOG_DAEMON|LOG_ERR,"Unable to call accept() on socket.");
        break;
    }

    /* Spawn a POSIX Server Thread to Handle Connected Socket */
    for(i=0; i < NUM_THREADS; i++){
        if(thread_bin_available[i]){
            thread_bin_available[i] = UNAVAILABLE;
            syslog(LOG_DAEMON|LOG_INFO,"Handling new connection on port %i",port);
            numClients++;
            info = (threadInfo*)malloc(sizeof(threadInfo));
            info->socket_connection = conn_s;
            info->thread_bin_index = i;
            pthread_create(&thread_bin[i],NULL,handleConnection, (void*)info);
            break;
        }
    }

    if(i > NUM_THREADS){
        syslog(LOG_DAEMON|LOG_ERR,"Unable to create thread to handle connection.  Continuing...");
    }
    
  }
  
  if(disconnectSpectrometers() == CONNECT_OK)
    syslog(LOG_DAEMON|LOG_INFO,"Spectrometers Successfully Disconnected");
  else
    syslog(LOG_DAEMON|LOG_ERR,"Unable to Disconnect Spectrometers");

  syslog(LOG_DAEMON|LOG_INFO,"Daemon Exited Politely.");
  exit(EXIT_SUCCESS);

}
Ejemplo n.º 11
0
      //! Load a plan into the vehicle
      //! @param[in] plan_id name of the plan
      //! @param[in] arg argument which may either be a maneuver or a plan specification
      //! @param[in] plan_startup true if a plan will start right after
      //! @return true if plan is successfully loaded
      bool
      loadPlan(const std::string& plan_id, const IMC::Message* arg,
               bool plan_startup = false)
      {
        if ((initMode() && !plan_startup) || execMode())
        {
          onFailure(DTR("cannot load plan now"));
          return false;
        }

        if (arg)
        {
          if (arg->getId() == DUNE_IMC_PLANSPECIFICATION)
          {
            const IMC::PlanSpecification* given_plan = static_cast<const IMC::PlanSpecification*>(arg);

            m_spec = *given_plan;
            m_spec.setSourceEntity(getEntityId());
          }
          else
          {
            // Quick plan
            IMC::PlanManeuver spec_man;
            const IMC::Maneuver* man = static_cast<const IMC::Maneuver*>(arg);

            if (man)
            {
              spec_man.maneuver_id = arg->getName();
              spec_man.data.set(*man);
              m_spec.clear();
              m_spec.maneuvers.setParent(&m_spec);
              m_spec.plan_id = plan_id;
              m_spec.start_man_id = arg->getName();
              m_spec.maneuvers.push_back(spec_man);
            }
            else
            {
              changeMode(IMC::PlanControlState::PCS_READY,
                         DTR("plan load failed: undefined maneuver or plan"));
              return false;
            }
          }
        }
        else
        {
          // Search DB
          m_spec.clear();

          if (!lookForPlan(plan_id, m_spec))
          {
            changeMode(IMC::PlanControlState::PCS_READY,
                       DTR("plan load failed: ") + m_reply.info);
            return false;
          }
        }

        if (!parsePlan(plan_startup))
        {
          changeMode(IMC::PlanControlState::PCS_READY,
                     DTR("plan validation failed: ") + m_reply.info);
          return false;
        }

        m_pcs.plan_id = m_spec.plan_id;

        if (plan_startup)
          onSuccess(DTR("plan loaded"), false);
        else
          changeMode(IMC::PlanControlState::PCS_READY, DTR("plan loaded"));

        return true;
      }