向主体添加力 post-完成?
Adding forces to body post-finalize?
我正在设置一个简单的模拟,我希望一个物体(一个盒子)在重力场中下落半秒钟,然后由于我施加在它上面的力克服重力而上升。
我已经尝试使用三种方法实现这种力量,使用 AddInForce
、AddInForceInWorld
和 AddForceElement
。由于这是在模拟 运行 时调用的,因此 AddForceElement
按预期抛出了错误。不过,对于另外两个,没有抛出任何错误或警告,但盒子显然没有作用在它上面的新力。
我也用 num_force_elements()
检查了新的力元素,但添加了 none。
这是我为这个事件计时的循环:
while( current_time < FLAGS_duration && !terminate){
if (current_time > 0.5 && !forced) {
std::cout << "\nAdding Force of type " << FLAGS_box_f << " at 0.5 seconds...\n";
// Add Rising Force to box
auto forces = drake::multibody::MultibodyForces<double>(plant);
drake::multibody::SpatialForce<double> forceup(Vector3d::Zero(), Vector3d(0, 0, 100));
if (FLAGS_box_f == "spring") {
plant.AddForceElement<LinearSpringDamper>(
plant.GetBodyByName("Box"), Vector3d::Zero(),
plant.world_body(), Vector3d(0, 0, 1),
0., 10., 1.);
} else if (FLAGS_box_f == "world") {
plant.GetBodyByName("Box").AddInForceInWorld(
plant_context,
forceup,
&forces);
} else {
plant.GetBodyByName("Box").AddInForce(
plant_context,
Vector3d::Zero(),
forceup,
plant.GetBodyByName("Box").body_frame(),
&forces);
}
plant.CalcForceElementsContribution(plant_context, &forces);
std::cout << "Plant: " << plant.num_force_elements() << " force_elements\n";
forced = true;
}
simulator.StepTo(current_time + time_delta);
current_time = simulator_context.get_time();
}
我不确定我的动作是否正确,而且仍然不太了解我在调用中存储力的 MultibodyForces 对象。
快速说明:您需要的是始终存在的力元素,但会根据时间改变其力输出。 built-in 个中的 None 个是这样的,所以你必须写一个。
@Joaquin Giraldo,
向模型添加外力的方法是使用输入力。 Drake 中的所有内容都是 input/output 端口。在这种情况下,您必须使用 MultibodyPlant::get_applied_spatial_force_input_port()
。
有关如何执行此操作的示例,请参阅文件 multibody/plant/test/externally_applied_spatial_force_test.cc
。
我正在设置一个简单的模拟,我希望一个物体(一个盒子)在重力场中下落半秒钟,然后由于我施加在它上面的力克服重力而上升。
我已经尝试使用三种方法实现这种力量,使用 AddInForce
、AddInForceInWorld
和 AddForceElement
。由于这是在模拟 运行 时调用的,因此 AddForceElement
按预期抛出了错误。不过,对于另外两个,没有抛出任何错误或警告,但盒子显然没有作用在它上面的新力。
我也用 num_force_elements()
检查了新的力元素,但添加了 none。
这是我为这个事件计时的循环:
while( current_time < FLAGS_duration && !terminate){
if (current_time > 0.5 && !forced) {
std::cout << "\nAdding Force of type " << FLAGS_box_f << " at 0.5 seconds...\n";
// Add Rising Force to box
auto forces = drake::multibody::MultibodyForces<double>(plant);
drake::multibody::SpatialForce<double> forceup(Vector3d::Zero(), Vector3d(0, 0, 100));
if (FLAGS_box_f == "spring") {
plant.AddForceElement<LinearSpringDamper>(
plant.GetBodyByName("Box"), Vector3d::Zero(),
plant.world_body(), Vector3d(0, 0, 1),
0., 10., 1.);
} else if (FLAGS_box_f == "world") {
plant.GetBodyByName("Box").AddInForceInWorld(
plant_context,
forceup,
&forces);
} else {
plant.GetBodyByName("Box").AddInForce(
plant_context,
Vector3d::Zero(),
forceup,
plant.GetBodyByName("Box").body_frame(),
&forces);
}
plant.CalcForceElementsContribution(plant_context, &forces);
std::cout << "Plant: " << plant.num_force_elements() << " force_elements\n";
forced = true;
}
simulator.StepTo(current_time + time_delta);
current_time = simulator_context.get_time();
}
我不确定我的动作是否正确,而且仍然不太了解我在调用中存储力的 MultibodyForces 对象。
快速说明:您需要的是始终存在的力元素,但会根据时间改变其力输出。 built-in 个中的 None 个是这样的,所以你必须写一个。
@Joaquin Giraldo,
向模型添加外力的方法是使用输入力。 Drake 中的所有内容都是 input/output 端口。在这种情况下,您必须使用 MultibodyPlant::get_applied_spatial_force_input_port()
。
有关如何执行此操作的示例,请参阅文件 multibody/plant/test/externally_applied_spatial_force_test.cc
。