情况
我意识到我一直在编写很多LeafSystem
类,它们对输入数据进行非常轻量级的操作并将其作为输出数据输出。它们都是无状态的,唯一的区别是转换函数。
这方面的一个例子是简单地重新排序输入数据的类或简单地去除不相关的输入数据的类。
因此,我想编写一个LeafSystem
将这个“转换函数”作为参数的类,以跳过每次我想以稍微不同的方式处理输入数据时都必须创建一个全新的类的麻烦。
这个想法是一个构造函数,它采用 astd::function
的形式,以及输入和输出向量的大小。
std::function<void(const Eigen::VectorBlock<const drake::VectorX<T>>&, Eigen::VectorBlock<drake::VectorX<T>>& )>;
“转换函数”可以在这个函子中实现。
一个示例用例是,如果我想将 3D 状态数据(x、y、z、roll、pitch、yaw)转换为 2D 状态数据(x、y、yaw),我可以编写一个仿函数,例如
void 3Dto2D(const Eigen::VectorBlock<const drake::VectorX<T>>& input, Eigen::VectorBlock<drake::VectorX<T>>& output)
{
output[0] = input[0]; //x
output[1] = input[1]; //y
output[2] = input[5]; //yaw
output[3] = input[6]; //x_dot
output[4] = input[7]; //y_dot
output[5] = input[11]; //yaw_dot
}
并将这个函子传递给这个“StateConverter”。
问题
我面临的问题是关于标量转换复制构造函数。当类具有特定于类型的成员对象时,如何实现它?
这个类的主体如下(为了完整性)
using ConversionFunc = std::function<void(const Eigen::VectorBlock<const drake::VectorX<T>>&, Eigen::VectorBlock<drake::VectorX<T>>& )>;;
// Some black magic to handle alias explicit template instantiation
template <typename T>
StateConverter<T>::StateConverter(ConversionFunc func, const unsigned int input_size, const unsigned int output_size) :
systems::LeafSystem<T>(systems::SystemTypeTag<StateConverter>{}),
input_idx(this->DeclareVectorInputPort("input_port", systems::BasicVector<T>(input_size)).get_index()),
output_idx(this->DeclareVectorOutputPort("output_port", systems::BasicVector<T>(output_size), &StateConverter::convert).get_index())
{
convert_func = func;
}
template <typename T>
void StateConverter<T>::convert(const drake::systems::Context<T>& context, systems::BasicVector<T>* output) const
{
const auto state = this->EvalVectorInput(context, input_idx)->get_value();
auto mutable_output = output->get_mutable_value();
convert_func(state, mutable_output);
}