Program Listing for File RouteValidator.hpp

Return to documentation for file (include/rmf_traffic/agv/RouteValidator.hpp)

/*
 * Copyright (C) 2020 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

#ifndef RMF_TRAFFIC__AGV__ROUTEVALIDATOR_HPP
#define RMF_TRAFFIC__AGV__ROUTEVALIDATOR_HPP

#include <rmf_traffic/schedule/Viewer.hpp>
#include <rmf_traffic/schedule/Negotiation.hpp>

#include <rmf_utils/clone_ptr.hpp>

namespace rmf_traffic {
namespace agv {

//==============================================================================
class RouteValidator
{
public:

  using ParticipantId = schedule::ParticipantId;
  using Route = rmf_traffic::Route;

  struct Conflict
  {
    Dependency dependency;
    Time time;
    std::shared_ptr<const rmf_traffic::Route> route;
  };

  //
  // TODO(MXG): It would be better to implement this as a coroutine generator so
  // that clients of this interface can decide whether they only care about the
  // first conflict or if they want to know all of the conflicts. This is not a
  // high priority because in the vast majority of cases when a conflict happens
  // it will only be with one participant. And since this is only meant to
  // provide a hint about which participant is causing conflicts, it is okay if
  // other participants are ignored.
  virtual std::optional<Conflict> find_conflict(
    const Route& route) const = 0;

  virtual std::unique_ptr<RouteValidator> clone() const = 0;

  virtual ~RouteValidator() = default;
};

//==============================================================================
class ScheduleRouteValidator : public RouteValidator
{
public:

  ScheduleRouteValidator(
    const schedule::Viewer& viewer,
    schedule::ParticipantId participant_id,
    Profile profile);

  ScheduleRouteValidator(
    std::shared_ptr<const schedule::Viewer> viewer,
    schedule::ParticipantId participant_id,
    Profile profile);

  template<typename... Args>
  static rmf_utils::clone_ptr<ScheduleRouteValidator> make(Args&& ... args)
  {
    return rmf_utils::make_clone<ScheduleRouteValidator>(
      std::forward<Args>(args)...);
  }

  ScheduleRouteValidator& schedule_viewer(const schedule::Viewer& viewer);

  const schedule::Viewer& schedule_viewer() const;

  ScheduleRouteValidator& participant(schedule::ParticipantId p);

  schedule::ParticipantId participant() const;

  // TODO(MXG): Make profile setters and getters

  // Documentation inherited
  std::optional<Conflict> find_conflict(const Route& route) const final;

  // Documentation inherited
  std::unique_ptr<RouteValidator> clone() const final;

  class Implementation;
private:
  rmf_utils::impl_ptr<Implementation> _pimpl;
};

//==============================================================================
class NegotiatingRouteValidator : public RouteValidator
{
public:

  class Generator
  {
  public:

    Generator(
      schedule::Negotiation::Table::ViewerPtr viewer,
      rmf_traffic::Profile profile);

    Generator(schedule::Negotiation::Table::ViewerPtr viewer);

    Generator& ignore_unresponsive(bool val = true);

    Generator& ignore_bystanders(bool val = true);

    NegotiatingRouteValidator begin() const;

    std::vector<rmf_utils::clone_ptr<NegotiatingRouteValidator>> all() const;

    const std::vector<schedule::ParticipantId>& alternative_sets() const;

    std::size_t alternative_count(schedule::ParticipantId participant) const;

    class Implementation;
  private:
    rmf_utils::impl_ptr<Implementation> _pimpl;
  };

  NegotiatingRouteValidator& mask(schedule::ParticipantId id);

  NegotiatingRouteValidator& remove_mask();

  NegotiatingRouteValidator next(schedule::ParticipantId id) const;

  const schedule::Negotiation::VersionedKeySequence& alternatives() const;

  operator bool() const;

  bool end() const;

  // Documentation inherited
  rmf_utils::optional<Conflict> find_conflict(const Route& route) const final;

  // Documentation inherited
  std::unique_ptr<RouteValidator> clone() const final;

  class Implementation;
private:
  NegotiatingRouteValidator();
  rmf_utils::impl_ptr<Implementation> _pimpl;
};

} // namespace agv
} // namespace rmf_traffic

#endif // RMF_TRAFFIC__AGV__ROUTEVALIDATOR_HPP