我意识到我已经编写了许多LeafSystem
类,这些类对输入数据进行非常轻量级的操作并将其作为输出数据吐出来。它们都是无状态的,唯一的区别是转换函数。
例如,一个类仅对输入数据进行重新排序,或者一个类仅剥离不相关的输入数据。
因此,我想编写一个LeafSystem
类,该类使用此“转换函数”作为参数,以免每次我想以略有不同的方式处理输入数据时都不得不创建一个全新类的麻烦方式。
这个想法是一个构造器,它采用std::function
形式,以及输入和输出向量大小。
std::function<void(const Eigen::VectorBlock<const drake::VectorX<T>>&, Eigen::VectorBlock<drake::VectorX<T>>& )>;
可以在此函子中实现“转换功能”。
一个示例用例是,如果我想将3D状态数据(x,y,z,侧倾,俯仰,偏航)转换为2D状态数据(x,y,偏航),我可以编写一个函子,例如
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);
}
答案 0 :(得分:1)
我最终创建了一个结构,该结构包含模板函数的所有3个必需实例
struct ConversionFunc
{
std::function<void(const Eigen::VectorBlock<const drake::VectorX<double>>&, Eigen::VectorBlock<drake::VectorX<double>>& )> double_impl;
std::function<void(const Eigen::VectorBlock<const drake::VectorX<drake::AutoDiffXd>>&, Eigen::VectorBlock<drake::VectorX<drake::AutoDiffXd>>& )> autodiff_impl;
std::function<void(const Eigen::VectorBlock<const drake::VectorX<drake::symbolic::Expression>>&, Eigen::VectorBlock<drake::VectorX<drake::symbolic::Expression>>& )> symbolic_impl;
};
复制构造函数中传递的是什么
我按如下方式创建结构
template <typename T>
void convert_func(const Eigen::VectorBlock<const VectorX<T>>& state, Eigen::VectorBlock<VectorX<T>>& output)
{
// Some example conversions
output[0] = state[4];
output[1] = state[6];
output[2] = state[12];
output[3] = state[14];
}
// I'm sure there's some way to automatically create these instantiations in the constructor of ConversionFunc...
ConversionFunc func;
func.double_impl = convert_func<double>;
func.autodiff_impl = convert_func<drake::AutoDiffXd>;
func.symbolic_impl = convert_func<drake::symbolic::Expression>;
并按照以下步骤将其传递给我的Converter
auto converter = builder.AddSystem(std::make_unique<StateConverter<double>>(func, 16, 4));
不幸的是,此方法似乎正在泄漏内存,导致抛出std::bad_alloc
...