This page contains a collection of tips and tricks for resolving common problems.
MultibodyPlant
Parsing
If you have a model file (e.g., .urdf, .sdf, .xml, .usd, etc.) that you are loading into a MultibodyPlant
using the Parser
class, and the model is not loading properly, then there are a few useful resources you might consider.
Documentation for the specific XML elements and attributes supported by the parser can be found here.
If you do run into some of the known limitations in Drake’s parsing support, you may consider using the make_drake_compatible_model
tool to convert your model file and assets into a format that Drake can parse. It is available in the manipulation Python package, and be used via e.g.:
python3 -m venv venv
venv/bin/pip install manipulation[mesh] --extra-index-url https://drake-packages.csail.mit.edu/whl/nightly/
venv/bin/python -m manipulation.make_drake_compatible_model {input_file} {output_file}
Unconnected QueryObject port
The error message will include the message, “The provided context doesn’t show a connection for the plant’s query input port.”
MultibodyPlant
(C++, Python)
requires a connection to SceneGraph
(C++,
Python) in order to evaluate contact via its QueryObject
(C++, Python). Attempts to evaluate output
ports that expose or depend on contact results (the geometric data and/or forces
that arise from the contact between bodies’ collision geometries) will fail.
Evaluating the time derivatives (e.g., when running a continuous simulation)
will likewise fail.
The connection can be reported as missing for several reasons:
- Was a
SceneGraph
instance created and connected? - Did you provide the right context?
- You’ve created and connected the systems in a
Diagram
(C++, Python) and allocated aContext
(C++, Python) for theDiagram
. - Make sure you extract the
MultibodyPlant
’s context from theDiagram
’sContext
. Do not allocate aContext
directly from the plant. UseSystem::GetMyContextFromRoot()
(C++, Python) to acquire the plant’sContext
from theDiagram
’s context; this will preserve all of the necessary connections. E.g.,
builder = DiagramBuilder() # Build plant and scene graph and automatically connect them. plant, scene_graph = AddMultibodyPlantSceneGraph( builder=builder, time_step=1e-3) ... diagram = builder.Build() # WRONG. This will create a Context for the plant only (no connected # SceneGraph). xdot = plant.EvalTimeDerivatives(context=plant.CreateDefaultContext()) context = diagram.CreateDefaultContext() # Extract the plant's context from the diagram's to invoke plant methods. plant_context = plant.GetMyContextFromRoot(root_context=context) xdot = plant.EvalTimeDerivatives(context=plant_context)
- You’ve created and connected the systems in a
System Framework
Context-System mismatch
The error message will include one of the following:
A function call on a FooSystem system named '::_::foo' was passed the root Diagram's Context instead of the appropriate subsystem context.
A function call on the root Diagram was passed a subcontext associated with its subsystem named '::_::foo' instead of the root context.
A function call on a BarSystem named '::_::bar' was passed the Context of a system named '::_::foo' instead of the appropriate subsystem Context.
Contexts and Systems: An Overview
For every System
(C++, Python) there is a
corresponding Context
(C++, Python). The System
and Context
work together. The Context
holds the data values and the
System
defines the operations on that data.
For example, a MultibodyPlant
(C++,
Python) is such a system. We can use an instance of a
MultibodyPlant
to create one or more Context
s. Each Context
contains the
continuous and discrete state values for the plant’s model. These Context
s
can be configured to represent the model in different configurations. However,
if we want to evaluate some mechanical property (e.g., composite inertia of a
robotic arm), we invoke a method on the plant, passing one of the contexts.
We can combine multiple System
s into a Diagram
(C++,
Python). The System
s within a Diagram
will typically have their
ports connected – this is how the System
s work together.
Context
s similarly form a parallel hierarchical structure. The Context
associated with a Diagram
is the combination of all of the Context
s
associated with the System
s inside that Diagram
. The port connections
between System
s in the Diagram
are mirrored in the Diagram
’s Context
.
Why did I get this error and how do I get rid of it?
Many System
APIs require a Context
. It is important to pass the right
Context
into the API. What’s the difference between a “right” and “wrong”
Context
?
- The right
Context
was allocated by theSystem
being evaluated. - If the
System
is part of aDiagram
, then theContext
provided should be a reference pointing inside theDiagram
sContext
(see below for how to do this).
The most common error is to pass the Diagram
’s Context
into a constituent
System
’s API. We’ll illustrate this using a Diagram
with a MultibodyPlant
.
The solution is to use either GetMyContextFromRoot()
(C++, Python) or
GetMyMutableContextFromRoot()
(C++, Python) as appropriate to extract a particular
System
’s Context
from its Diagram
’s Context
.
builder = DiagramBuilder()
plant, _ = AddMultibodyPlantSceneGraph(builder=builder, time_step=1e-3)
... # Populate the plant with interesting stuff.
diagram = builder.Build()
# Create a Context for diagram.
root_context = diagram.CreateDefaultContext()
my_body = plant.GetBodyByName("my_body")
X_WB = RigidTransform(...) # Define a pose for the body.
# Error! plant has been given diagram's context.
plant.SetFreeBodyPose(context=root_context, body=base, X_WB=X_WB_desired)
# Get the Context for plant from diagram's context.
plant_context = plant.GetMyContextFromRoot(root_context=root_context)
# Successful operation; the provided context belongs to plant.
plant.SetFreeBodyPose(context=plant_context, body=base, X_WB=X_WB_desired)
See the notes on System Compatibility for further discussion.
PyPI (pip)
No candidate version for this platform
When installing Drake from PyPI on older platforms such as Ubuntu Focal, you may
receive the error “no candidate version for this platform”. This is caused by
older versions of pip
which do not recognize the manylinux
platform used by
Drake. This is remedied by installing a newer version of pip
.
Use of a Python virtual environment may be required in order to get a newer
version of pip
, e.g.:
python3 -m venv env
env/bin/pip install --upgrade pip
env/bin/pip install drake
source env/bin/activate
Image rendering
GL and/or DISPLAY
When performing image rendering (i.e., camera simulation), sometimes you may need to configure your computer to provide Drake sufficient access to core graphics libraries.
Drake renders images using the
RenderEngine
abstract base class, which is typically configured using the
CameraConfig
data structure via YAML, which can specify a concrete RenderEngine
subclass to
be used. Refer to the
hardware_sim
example for details.
If you are using either RenderEngineGl
, or RenderEngineVtk
under the
(non-default) setting backend = "GLX"
, then you must ensure that prior to
using Drake the $DISPLAY
environment variable is set to an available X11
display server (e.g., ":1"
). If you are running as desktop user (not over
ssh), then $DISPLAY
will probably already be set correctly.
For remote rendering (e.g., in the cloud) we recommend avoiding needing any
$DISPLAY
by using only RenderEngineVtk
and only with its default backend
.
If you do need a display in the cloud, you’ll need to run a program such as
PyVirtualDisplay
, Xvfb
, or a full Xorg
server to provide it.
Build problems
Out of memory
When compiling Drake from source, the build might run out of memory. The error message will include the message, “cc: fatal error: Killed signal terminated program cc1plus”.
By default, the Drake build will try use all available CPU and RAM resources on the machine. Sometimes, when there is not enough RAM per CPU, the build might crash because it tried to run a compiler process on every vCPU and together those compilation jobs consumed more RAM than was available.
In this case, you’ll need to add a bazel configuration dotfile to your home
directory. Create a text file at $HOME/.bazelrc
with this content:
build --jobs=HOST_CPUS*0.4
This instructs the build system to use only 40% of the available vCPUs. You may
tune the fraction up or down to balance build speed vs resource crashes. You may
also specify an exact number like build --jobs=2
instead of a fraction.
The dotfile will affect any Bazel builds that you run. If you prefer to change
only the Drake build instead of all Bazel builds, you may place the dotfile in
the Drake source tree at drake/user.bazelrc
instead of your home directory.
Note that the concurrency level passed to make
(e.g., make -j 2
) does not
propagate through to affect the concurrency of most of Drake’s build steps; you
need to configure the dotfile in order to control the build concurrency.