Exemplo n.º 1
0
      //! Update yoyo motion
      //! @param[in] startup whether or not the yoyo motion is starting now
      //! @param[in] state_z current z position (negative if altitude)
      //! @param[in] pitch current pitch angle
      //! @return new pitch command
      float
      update(bool startup, float state_z, float pitch)
      {
        if (!startup)
        {
          double t_dist = m_dir * (state_z - m_target_z);

          if (t_dist >= 0)
          {
            m_old_pitch = trimPitch(m_dir * m_pitch_ref, pitch);
            return m_old_pitch;
          }

          m_dir = -m_dir;
          m_source_z = m_target_z;
        }
        else if (!m_dir)
        {
          // Start *or* resume (after being off-track)
          // yoyo mode by figuring out whether to go up or down
          double min_z = m_z_ref - m_amplitude;
          double max_z = m_z_ref + m_amplitude;
          double dmin = std::fabs(state_z - min_z);
          double dmax = std::fabs(state_z - max_z);

          m_dir = dmin < dmax ? -1 : 1;
          m_source_z = state_z;
        }

        m_target_z = m_z_ref - m_dir * m_amplitude;

        std::stringstream ss;
        ss << (m_dir < 0 ? "descending " : "ascending ")
           << m_source_z << " --> " <<  m_target_z;
        m_task->debug("%s", ss.str().c_str());

        // Trim pitch value for more smooth control
        // (this is an optional measure, in principle pitch controller
        //  should "know" how to proceed smoothly)
        m_old_pitch = trimPitch(m_dir * m_pitch_ref, pitch);

        return m_old_pitch;
      }
Exemplo n.º 2
0
 //! Stabilize pitch in a certain value
 //! @param[in] desired_pitch pitch angle at which to stabilize
 //! @param[in] current_pitch current pitch angle
 //! @return pitch angle to command
 inline float
 stabilize(float desired_pitch, float current_pitch)
 {
   return trimPitch(desired_pitch, current_pitch);
 }
Exemplo n.º 3
0
      //! Update yoyo motion
      //! @param[in] startup whether or not the yoyo motion is starting now
      //! @param[in] depth current depth position
      //! @param[in] altitude current altitude position
      //! @param[in] pitch current pitch angle
      //! @return new pitch command
      float
      update(bool startup, float depth, float alt, float pitch)
      {
        float state_z;
        if (m_zunits == IMC::Z_DEPTH)
          state_z = depth;
        else
          state_z = alt;

        if (m_invert)
        {
          m_dir = -m_dir;
          m_source_z = m_target_z;
          m_invert = false;
          m_task->debug("ascending due to brake");
        }
        else if (!startup)
        {
          double t_dist;
          if (m_zunits == IMC::Z_DEPTH)
          {
            // special case for yoyo at surface.
            if (m_z_ref + m_amplitude < c_dist_to_ref)
            {
              m_old_pitch = trimPitch(m_dir * m_pitch_ref, pitch);
              return m_old_pitch;
            }

            t_dist = m_dir * (state_z - m_target_z);
          }
          else
          {
            t_dist = m_dir * (m_target_z - state_z);
          }

          if (t_dist >= std::min(m_amplitude, c_dist_to_ref)
              && withinLimits(depth, alt))
          {
            m_old_pitch = trimPitch(m_dir * m_pitch_ref, pitch);
            return m_old_pitch;
          }

          m_dir = -m_dir;
          m_source_z = m_target_z;
        }
        else if (m_dir == DIR_NONE)
        {
          // Start *or* resume (after being off-track)
          // yoyo mode by figuring out whether to go up or down
          double min_z = m_z_ref - m_amplitude;
          double max_z = m_z_ref + m_amplitude;
          double dmin = std::fabs(state_z - min_z);
          double dmax = std::fabs(state_z - max_z);

          if (m_zunits == IMC::Z_DEPTH)
          {
            if (max_z > c_dist_to_ref)
              m_dir = dmin < dmax ? DIR_DOWN : DIR_UP;
            else
              m_dir = DIR_UP;
          }
          else
          {
            m_dir = dmin < dmax ? DIR_UP : DIR_DOWN;
          }

          m_source_z = state_z;
        }

        // update target
        if (m_zunits == IMC::Z_DEPTH)
        {
          // keep vehicle within surface and maximum absolute depth
          if (m_dir == DIR_UP)
            m_target_z = std::max(0.0f, m_z_ref - m_amplitude);
          else
            m_target_z = std::min(m_max_depth - c_depth_margin, m_z_ref + m_amplitude);
        }
        else
        {
          // keep the vehicle above minimum altitude
          if (m_dir == DIR_UP)
            m_target_z = m_z_ref + m_amplitude;
          else
            m_target_z = std::max(m_min_alt, m_z_ref - m_amplitude);
        }

        std::stringstream ss;
        ss << (m_dir < 0 ? "descending " : "ascending ")
           << m_source_z << " --> " <<  m_target_z;
        m_task->debug("%s", ss.str().c_str());

        // Trim pitch value for more smooth control
        // (this is an optional measure, in principle pitch controller
        //  should "know" how to proceed smoothly)
        m_old_pitch = trimPitch(m_dir * m_pitch_ref, pitch);

        return m_old_pitch;
      }