Ошибка визуализации, отображаемая во время линеаризации / LQR для Acrobot, но не для Double Pendulum

#drake

#drake

Вопрос:

Я пытаюсь перенести скрипты, которые я сделал для double pendulum, в acrobot (двигаясь в сторону большей недоработки). Делая это, я увидел, что скрипт контроллера LQR (вдохновленный в основном из этого ноутбука из недоработанного курса) выдает ошибки во время линеаризации / создания контроллера LQR. Код идентичен, за исключением изменений для одного привода вместо 2.

Странно то, что ошибка связана с подключением портов геометрии во время команды Linearization / creating LQR, которая не отображается при использовании double pendulum. Ошибка, указанная во время линеаризации / LQR, равна:

 RuntimeError: The geometry query input port (see MultibodyPlant::get_geometry_query_input_port()) of this MultibodyPlant is not connected. Please connect thegeometry query output port of a SceneGraph object (see SceneGraph::get_query_output_port()) to this plants input port in a Diagram.

 

Я предположил, что, поскольку сценарий работал для double pendulum, он будет работать и для acrobot, но, похоже, я, вероятно, допустил ошибку, я думаю. Комментирование строк для LQR и его соединений на диаграмме приводит к запуску моделирования с заданными начальными условиями, что делает его еще более запутанным для меня. Я не могу проверить визуализацию диаграммы, так как ошибка появляется до того, как я смогу запустить builder.Build() .

Блокнот Google colab для воспроизведения ошибки можно увидеть здесь. В первом разделе есть сценарий acrobot с ошибкой, а во втором разделе — тот же сценарий для double pendulum, который выполняется, как и ожидалось.

Редактировать: другой метод, который я пробовал, но не сработал:

 builder = DiagramBuilder()
scene_graph = builder.AddSystem(SceneGraph())
plant = builder.AddSystem(MultibodyPlant(0.001))
plant.RegisterAsSourceForSceneGraph(scene_graph)


# Load the Acrobot description from URDF file
parser = Parser(plant)
# parser = Parser(plant, scene_graph)
parser.AddModelFromFile("Acrobot.urdf")

# # Reduce/remove gravity
plantGravityField = plant.gravity_field()
plantGravityField.set_gravity_vector([0,0,0])

plant.Finalize()
assert plant.geometry_source_is_registered()


builder.Connect(scene_graph.get_query_output_port(), plant.get_geometry_query_input_port())
builder.Connect(plant.get_geometry_poses_output_port(), scene_graph.get_source_pose_port(plant.get_source_id()))
 

Здесь я явно подключаю порт ввода запроса геометрии объекта к порту вывода запроса графика сцены, но все равно получаю ту же ошибку во время линеаризации.

Комментарии:

1. Я не проверял ваш код, но похоже, что вы ввели новую геометрию столкновения в проблему, что означает, что MultibodyPlant теперь необходимо подключить к SceneGraph (который является механизмом столкновения).

2. Я предположил, что AddMultibodyPlantSceneGraph() функция обработала эти соединения. Например, в упражнении one_d_hopper в главе 4 недостаточно разработанного курса робототехники есть геометрия столкновения и столкновение, но конструктор диаграмм там использует только AddMultibodyPlantSceneGraph() функцию.

3. Кроме того, если я последую предложению об ошибке и запущу builder.Connect(scene_graph.get_query_output_port(), plant.get_geometry_query_input_port()) , тогда появится сообщение об ошибке RuntimeError: Input port is already wired. . Я думал, что это делается с помощью AddMultibodyPlantSceneGraph() .

4. В этом случае вы передаете a Context , у которого нет SceneGraph прикрепленного? Вы захотите создать контекст диаграммы, а затем передать субтекст … (например, с GetMyContextFromRoot помощью ).

5. Это действительно имеет смысл. Есть ли тогда способ создать контекст из диаграммы с контроллером LQR внутри нее перед построением диаграммы? Я думаю, тогда имеет смысл создать диаграмму только с использованием MultibodyPlant и Scene_graph и предоставить порты, необходимые для LQR, а затем создать другую диаграмму, которая соединяет построенную диаграмму с LQR, используя контекст построенной диаграммы?

Ответ №1:

Одним из решений моей проблемы было удаление геометрии столкновения из файла urdf. Линеаризация прошла успешно с использованием Linearize LinearQuadraticRegulator функций или.

Обновление: теперь я понимаю немного больше:

Drake использует scene_graph для проверки / моделирования столкновений, и, следовательно, если в urdf используются геометрии столкновений, scene_graph необходимо подключить к порту ввода запроса геометрии для передачи информации о столкновениях на завод. Для Linearization / LQR, если геометрия столкновения находится в urdf, он ожидает, что этот порт будет подключен для моделирования (естественно). Но поскольку в функцию Linearization / LQR передается только объект, он не знает об этом, поскольку scene_graph отсутствует.

В моем случае у меня нет никаких столкновений в точках, где я хочу линеаризовать / управлять с помощью LQR (кроме того, обычно, вероятно, плохая идея использовать LQR при столкновениях). Итак, поскольку столкновения не моделируются, я просто удалил части геометрии столкновения в urdf, используемые для линеаризации. Я включаю их для других целей, таких как оптимизация траектории и моделирование.