You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/drake-master/multibody/parsing/detail_sdf_geometry.h

231 lines
11 KiB

#pragma once
#include <memory>
#include <optional>
#include <string>
#include <drake_vendor/sdf/Collision.hh>
#include <drake_vendor/sdf/Geometry.hh>
#include <drake_vendor/sdf/Visual.hh>
#include "drake/common/diagnostic_policy.h"
#include "drake/geometry/geometry_instance.h"
#include "drake/geometry/geometry_roles.h"
#include "drake/geometry/shape_specification.h"
#include "drake/math/rigid_transform.h"
#include "drake/multibody/parsing/detail_sdf_diagnostic.h"
#include "drake/multibody/parsing/package_map.h"
#include "drake/multibody/plant/coulomb_friction.h"
namespace drake {
namespace multibody {
namespace internal {
/* Used for resolving URIs / filenames. */
using ResolveFilename = std::function<std::string (
const SDFormatDiagnostic&, std::string)>;
/* Given an sdf::Geometry object representing a <geometry> element from an SDF
file, this method makes a new drake::geometry::Shape object from this
specification.
If no recognizable geometry is specified, nullptr is returned. If the geometry
is recognized, but malformed, emits an error. When the error policy is set to
not throw it returns std::nullopt. */
std::optional<std::unique_ptr<geometry::Shape>> MakeShapeFromSdfGeometry(
const SDFormatDiagnostic& diagnostic,
const sdf::Geometry& sdf_geometry,
ResolveFilename resolve_filename);
/* Given an sdf::Visual object representing a <visual> element from an SDF
file, this method makes a new drake::geometry::GeometryInstance object from
this specification at a pose `X_LG` relatve to its parent link.
This method returns nullptr when the given SDF specification corresponds
to an uninterpreted geometry type:
- `sdf::GeometryType::EMPTY` (`<empty/>` SDF tag.)
- `sdf::GeometryType::HEIGHTMAP` (`<heightmap/>` SDF tag.)
If the geometry is malformed, emits an error. When the error policy is not
set to throw it returns an std::nullopt.
<!-- TODO(SeanCurtis-TRI): Ultimately, a module for what we parse should be
written outside of this _internal_ namespace. This should go there and
merely reference it. -->
<h2>Targeting Renderers</h2>
In addition to the standard SDF <visual> hierarchy, Drake offers an additional
tag `<drake:accepting_renderer>`:
```
<visual>
<geometry ... />
<drake:accepting_renderer>renderer_name</drake:accepting_renderer>
...
</visual>
```
The new tag serves as a list of renderers for which this visual is targeted.
- The _value_ of the tag is the name of the renderer.
- If the _value_ is empty, that is a parsing error.
- If no instance of `<drake:accepting_renderer>` every renderer will be given
the chance to reify this visual geometry.
- Multiple instances of this tag are allowed. Each instance adds a renderer to
the list of targeted renderers.
This feature is one way to provide multiple visual representations of a body.
*/
std::optional<std::unique_ptr<geometry::GeometryInstance>>
MakeGeometryInstanceFromSdfVisual(
const SDFormatDiagnostic& diagnostic,
const sdf::Visual& sdf_visual, ResolveFilename resolve_filename,
const math::RigidTransformd& X_LG);
/* Extracts the material properties from the given sdf::Visual object.
The sdf::Visual object represents a corresponding <visual> tag from an SDF
file. The material properties are placed into both a
geometry::IllustrationProperties and geometry::PerceptionProperties as follows:
<!-- NOTE: Lines longer than 80 columns required for the doxygen tables. -->
| Group | Name | Type | Description |
| :---: | :---------: | :-------------: | :---------- |
| phong | diffuse | Vector4<double> | The normalized rgba values for the diffuse color |
| phong | ambient | Vector4<double> | The normalized rgba values for the ambient color |
| phong | specular | Vector4<double> | The normalized rgba values for the specular color |
| phong | emissive | Vector4<double> | The normalized rgba values for the emissive color |
| phong | diffuse_map | string | A resolvable URI to a png image that will be applied as a diffuse map. |
These are properties to be used in the
<a href="https://en.wikipedia.org/wiki/Phong_reflection_model">Phong
lighting model</a> and are taken from the similarly named property tags (see
below). If any of `ambient`, `diffuse`, `specular`, or `emissive` tags are
missing, that property will be omitted from the property set and the impact
of those missing properties will depend on the downstream consumers documented
handling of missing parameters. If any of the tags are malformed, sdformat
will treat those properties as "missing" and they will not be included in
the property set.
<!-- TODO(SeanCurtis-TRI): Consider changing the behavior for unspecified tags
to provide the material value as specified in the current (12/11/18) sdf
specification (http://sdformat.org/spec?ver=1.6&elem=material).
This is captured in the issue:
https://github.com/RobotLocomotion/drake/issues/10193 -->
The material properties come from the child <material> tag. E.g.,
@code{xml}
<visual>
<geometry>
...
</geometry>
<material>
<ambient>r_a g_a b_a a_a</ambient>
<diffuse>r_d g_d b_d a_d</diffuse>
<specular>r_s g_s b_s a_s</specular>
<emissive>r_e g_e b_e a_e</emissive>
</material>
</visual>
@endcode
An instance of geometry::IllustrationProperties will be returned. If there is
no material tag, no material property tags, or no successfully parsed material
property tags, the property set will be empty. If the material is malformed
an error will be emitted. If the error policy is not set to throw, an
std::nullopt will be returned. */
std::optional<geometry::IllustrationProperties>
MakeVisualPropertiesFromSdfVisual(
const SDFormatDiagnostic& diagnostic,
const sdf::Visual& sdf_visual, ResolveFilename resolve_filename);
/* Computes the pose `X_LC` of frame C (the "canonical frame" of the geometry)
relative to the link L containing the collision, given an `sdf_collision`
stemming from the parsing of a `<collision>` element in an SDF file and its
pose `X_LG`, where `G` represents the frame for the geometry of that collision
element. */
math::RigidTransformd MakeGeometryPoseFromSdfCollision(
const sdf::Collision& sdf_collision, const math::RigidTransformd& X_LG);
/* @anchor sdf_contact_material
Parses the drake-relevant collision properties from a <collision> element.
Specifically, looks for <drake:proximity_properties> tag to find drake-specific
geometry collision (or "proximity") properties. The set of tags are enumerated
in the table below. Each tag should be of the form:
@code{xml}
<tag>real_value</tag>
@endcode
It returns a valid instance of ProximityProperties. There are not default
values for these tags (except for friction -- see below); if the tag is
missing, the corresponding property will be missing from the property set.
If the collision element is malformed it emits an error. If the error
policy is set to not throw an std::nullopt is returned instead.
Mapping from SDF tag to geometry property. See
@ref YET_TO_BE_WRITTEN_HYDROELASTIC_GEOMETRY_MODULE for details on the
semantics of these properties.
| Tag | Group | Property | Notes |
| :------------------------------: | :----------: | :-----------------------: | :------------------------------------------------------------------------------------------------------------------------------: |
| drake:mesh_resolution_hint | hydroelastic | resolution_hint | Required for shapes that require tessellation to support hydroelastic contact. |
| drake:hydroelastic_modulus | hydroelastic | hydroelastic_modulus | Finite positive value. Required for compliant hydroelastic representations. |
| drake:hunt_crossley_dissipation | material | hunt_crossley_dissipation | |
| drake:relaxation_time | material | relaxation_time | Required when using a linear model of dissipation, for instance with the SAP solver. |
| drake:mu_dynamic | material | coulomb_friction | See note below on friction. |
| drake:mu_static | material | coulomb_friction | See note below on friction. |
| drake:rigid_hydroelastic | hydroelastic | compliance_type | Requests a rigid hydroelastic representation. Cannot be combined *with* soft_hydroelastic. |
| drake:compliant_hydroelastic | hydroelastic | compliance_type | Requests a compliant hydroelastic representation. Cannot be combined *with* rigid_hydroelastic. Requires a value for hydroelastic_modulus. |
<h3>Coefficients of friction</h3>
Parsing coefficients of friction has a relatively complicated protocol:
1. If one of `<drake:mu_dynamic>` *or* `<drake:mu_static>` is present, the
property of type CoulombFriction<double> will be instantiated with both
values initialized to the single value. An exception will be thrown
- if the value is negative.
2. If both `<drake:mu_dynamic>` and `<drake:mu_static>` tags are present, the
CoulombFriction<double> will contain both values. An exception will be
thrown if:
- either value is negative, or
- `mu_dynamic` is greater than `mu_static`.
3. If *both* tags are missing, the parser will look for two coefficients
in the SDF tag path: `<surface><friction><ode><mu>` and
`<surface><friction><ode><mu2>`.
a. See MakeCoulombFrictionFromSdfCollisionOde() for failure modes.
4. If no meaningful friction coefficients are found, a default value will be
created (see default_friction()).
As long as no exception is thrown, the resulting ProximityProperties will have
the ('material', 'coulomb_friction') property. */
std::optional<geometry::ProximityProperties>
MakeProximityPropertiesForCollision(
const SDFormatDiagnostic& diagnostic,
const sdf::Collision& sdf_collision);
/* Parses friction coefficients from `sdf_collision`.
This method looks for the definitions specific to ODE, as given by the SDF
specification in `<collision><surface><friction><ode>`. Drake understands
`<mu>` as the static coefficient of friction and `<mu2>` as the dynamic
coefficient of friction. Consider the example below:
```xml
<collision>
<surface>
<friction>
<ode>
<mu>0.8</mu>
<mu2>0.3</mu2>
</ode>
</friction>
</surface>
</collision>
```
If mu or mu2 are not found, an error is emitted. If the error policy is not
set to throw an std::nullopt is returned. */
std::optional<CoulombFriction<double>>
MakeCoulombFrictionFromSdfCollisionOde(
const SDFormatDiagnostic& diagnostic,
const sdf::Collision& sdf_collision);
} // namespace internal
} // namespace multibody
} // namespace drake