You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/drake-master/systems/primitives/demultiplexer.h

130 lines
4.3 KiB

#pragma once
#include <memory>
#include <vector>
#include "drake/common/drake_copyable.h"
#include "drake/systems/framework/leaf_system.h"
namespace drake {
namespace systems {
/// This system splits a vector valued signal on its input into multiple
/// outputs.
///
/// The input to this system directly feeds through to its output.
///
/// @system
/// name: Demultiplexer
/// input_ports:
/// - u0
/// output_ports:
/// - y0
/// - ...
/// - y(N-1)
/// @endsystem
///
/// @tparam_default_scalar
/// @ingroup primitive_systems
template <typename T>
class Demultiplexer final : public LeafSystem<T> {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(Demultiplexer)
/// Constructs %Demultiplexer with one vector valued output ports with sizes
/// specified as the vector @p output_ports_sizes. The number of output ports
/// is the length of this vector. The size of each output port is the value of
/// the corresponding element of the vector @p output_ports_sizes.
///
/// @system
/// name: Demultiplexer
/// input_ports:
/// - u0
/// output_ports:
/// - y0
/// - ...
/// - y(output_ports_sizes.size() - 1)
/// @endsystem
///
/// @throws std::exception if @p output_ports_sizes is a zero length vector.
/// @throws std::exception if any element of the @p output_ports_sizes is
/// zero. Therefore, the Demultiplexer does not allow zero size output ports.
///
/// @param output_ports_sizes Contains the sizes of each output port. The
/// number of output ports is determined by the length of @p
/// output_ports_sizes. The accumulative value of the all the values in @p
/// output_ports_sizes will be the size of the input port.
explicit Demultiplexer(const std::vector<int>& output_ports_sizes);
/// Constructs %Demultiplexer with one vector valued input port of size
/// @p size and vector valued output ports of size @p output_ports_size.
///
/// @system
/// name: Demultiplexer
/// input_ports:
/// - u0
/// output_ports:
/// - y0
/// - ...
/// - y((size / output_ports_size) - 1)
/// @endsystem
///
/// @throws std::exception if output_ports_sizes can not exactly divide @p
/// size. The number of output ports is therefore `size / output_ports_size`.
///
/// @param size is the size of the input signal to be demultiplexed into its
/// individual components.
/// @param output_ports_size The size of the output ports. @p size must be
/// a multiple of @p output_ports_size.
explicit Demultiplexer(int size, int output_ports_size = 1);
/// Scalar-converting copy constructor. See @ref system_scalar_conversion.
template <typename U>
explicit Demultiplexer(const Demultiplexer<U>&);
const std::vector<int>& get_output_ports_sizes() const {
return output_ports_sizes_;
}
private:
// Sets the port_index-th output port value.
void CopyToOutput(const Context<T>& context, OutputPortIndex port_index,
BasicVector<T>* output) const;
// Return a std vector with size of 'size / output_ports_size' and all values
// as @p output_ports_sizes.
static const std::vector<int> CalcOutputPortsSizes(int size,
int output_ports_size) {
// The size must be a multiple of output_ports_size.
DRAKE_DEMAND(size % output_ports_size == 0);
const int num_output_ports = size / output_ports_size;
return std::vector<int>(num_output_ports, output_ports_size);
}
// Return a std vector with the same size as the input @p output_ports_sizes.
// The values are calculated as the start index of the output port inside the
// input port vector.
static const std::vector<int> CalcOutputPortsStart(
const std::vector<int>& output_ports_sizes) {
const int num_output_ports = output_ports_sizes.size();
// Require the number of output ports should be greater than 1.
DRAKE_DEMAND(num_output_ports >= 1);
std::vector<int> output_ports_start;
output_ports_start.resize(num_output_ports);
output_ports_start[0] = 0;
for (int i = 1; i < num_output_ports; i++) {
output_ports_start[i] =
output_ports_start[i - 1] + output_ports_sizes[i - 1];
}
return output_ports_start;
}
const std::vector<int> output_ports_sizes_;
const std::vector<int> output_ports_start_;
};
} // namespace systems
} // namespace drake