Skip to content

[AO migration] ArticulatedObject API#1312

Merged
aclegg3 merged 23 commits intomasterfrom
ao-migration-base-api
Jun 16, 2021
Merged

[AO migration] ArticulatedObject API#1312
aclegg3 merged 23 commits intomasterfrom
ao-migration-base-api

Conversation

@aclegg3
Copy link
Copy Markdown
Contributor

@aclegg3 aclegg3 commented Jun 14, 2021

Motivation and Context

This PR migrates base ArticulatedObject functionality from the prototype branch #1273.

Changes include:

  • ArticulatedObject base class with BulletArticulatedObject derived implementation.
  • URDFImporter base class and BulletURDFImporter derived implementation (construct BulletArticulatedObject from io::URDF::Model )
  • Basic API functionality: joint/DoF position|velocity|force/torque get/set, motion types, NavMesh support for Static, contact query, joint limits and clamping, link queries.
  • Wrapper/Manager interface for ArticulatedObjects.
  • URDF support in SceneInstance metadata

How Has This Been Tested

New tests for MetaDataMediator, AttributesManagers, and ArticulatedObject API.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have completed my CLA (see CONTRIBUTING)
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@facebook-github-bot facebook-github-bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Jun 14, 2021
Comment thread src/esp/metadata/MetadataMediator.h Outdated
Comment thread src/esp/physics/bullet/objectWrappers/ManagedBulletArticulatedObject.h Outdated
Comment thread src/esp/metadata/MetadataMediator.h
Comment thread src/esp/io/JsonStlTypes.h
Comment on lines +138 to +162
template <>
inline bool readMember(const JsonGenericValue& d,
const char* tag,
std::map<std::string, float>& val) {
if (d.HasMember(tag)) {
if (d[tag].IsObject()) {
const auto& jCell = d[tag];
for (rapidjson::Value::ConstMemberIterator it = jCell.MemberBegin();
it != jCell.MemberEnd(); ++it) {
const std::string key = it->name.GetString();
if (it->value.IsFloat()) {
val.emplace(key, it->value.GetFloat());
} else {
LOG(ERROR) << "Invalid float value specified in JSON config " << tag
<< " at " << key << ". Skipping.";
}
} // for each value
return true;
} else { // if member is object
LOG(ERROR) << "Invalid JSON Object value specified in JSON config at "
<< tag << "; Unable to populate std::map.";
}
} // if has tag
return false;
} // readMember<std::map<std::string, float>>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to note about this function - the 2 other container-based specializations of readMember will return true even if the value is not found in the json (they return false if some format error occurs while reading a tag), although this one does not (and it is expected that this one does not). The non-container versions return false if the tag is not present.

@eundersander and I have been discussing potentially changing this behavior for the container-based readMember, and their matching addMember methods. Just wanting to leave a note here about this.


if (info.type == AssetType::FRL_PTEX_MESH) {
if (info.type == AssetType::PRIMITIVE) {
buildPrimitiveAssetData(info.filepath);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this assumes the AssetAttributesManager has already registered a primitive asset with this name. As such, this won't support RenderReplay currently.

Copy link
Copy Markdown
Contributor

@jturner65 jturner65 Jun 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A possible solution to this would be the string-based construction of primitives. Since primitive attributes names encode their structure, and do not allow for renaming, we could reverse engineer the required attributes if it is missing by using the name.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking this might be a viable option also.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that PR #1314 addresses this gap, thanks @jturner65!

Copy link
Copy Markdown
Contributor

@jturner65 jturner65 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once some method docstrings are provided, this looks great! Very exciting to get the main AO stuff into master.

@aclegg3 aclegg3 requested a review from bigbike June 14, 2021 16:24
Comment thread src/esp/physics/URDFImporter.cpp Outdated
Comment thread src/esp/physics/URDFImporter.h
Copy link
Copy Markdown
Contributor

@Skylion007 Skylion007 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of performance / style nits

Comment thread src/esp/physics/bullet/BulletArticulatedObject.cpp Outdated
Comment thread src/esp/physics/bullet/BulletArticulatedObject.cpp Outdated
Comment thread src/esp/physics/bullet/BulletURDFImporter.h Outdated
Copy link
Copy Markdown
Contributor

@bigbike bigbike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really a big diff.
Not so sure if it can be further divided into even smaller ones.
Just reviewed part of it.

Comment thread src/esp/physics/bullet/BulletArticulatedObject.cpp Outdated
Comment thread src/esp/physics/bullet/BulletArticulatedObject.cpp Outdated
Comment thread src/esp/physics/bullet/BulletArticulatedObject.cpp Outdated
Comment thread src/esp/assets/ResourceManager.cpp Outdated
Comment thread src/esp/physics/bullet/BulletPhysicsManager.cpp Outdated
Comment thread src/esp/assets/ResourceManager.cpp Outdated
Comment thread src/esp/assets/ResourceManager.cpp Outdated
std::shared_ptr<io::URDF::Material> material =
visual.m_geometry.m_localMaterial;
if (material) {
visualMeshInfo.overridePhongMaterial = assets::PhongMaterialColor();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these models glbs? It is supposed to use Pbr instead of Phong. Where does it override such a choice (using Phong not Pbr)? Would you show me the a code pointer?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: in Pbr, now I coded it up the shadows. So in the future, if we would like to leverage it, we need to use Pbr shader + Pbr drawables.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. All of our test models define a 4d color. We've been treating them as Phong, but we could instead treat them as PBR with no textures.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where this override material color is consumed to register a new Phong material and cache the custom LoadedAssetInfo.

Comment thread src/esp/io/JsonStlTypes.h Outdated
if (it->value.IsFloat()) {
val.emplace(key, it->value.GetFloat());
} else {
LOG(ERROR) << "Invalid float value specified in JSON config " << tag
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be buried easily in the screen output.
would this error lead to fatal error in the future? If yes, use CORRADE_ASSERT here to stop it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Counterpoint: LOG(ERROR) fits with our existing JSON-reading convention. An assert isn't appropriate because this is a runtime validation of data, whereas asserts are to catch programmer errors in code. Also, treating the error as fatal is inappropriate (it's up to the calling JSON code to decide the severity of a failed parse; some callers may want to just have the error logged but then keep going).

explicit SceneObjectInstanceAttributes(const std::string& handle);
explicit SceneObjectInstanceAttributes(
const std::string& handle,
const std::string& type = "SceneObjectInstanceAttributes");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just predict by the variable name: type.
I would define an enum for a type instead of using a string simply because a string can be random.
But I guess no chance to change it now (otherwise it requires a lot of code refactoring.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, agreed it seems like a later refactor.

Comment thread src/esp/metadata/attributes/SceneAttributes.h
Copy link
Copy Markdown
Contributor

@eundersander eundersander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left comments. Looks like just some straightforward code cleanup remaining.

Comment thread src/esp/assets/ResourceManager.cpp Outdated
Comment thread src/esp/io/JsonStlTypes.h Outdated
Comment thread src/esp/io/JsonStlTypes.h
template <>
inline bool readMember(const JsonGenericValue& d,
const char* tag,
std::map<std::string, float>& val) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach of implementing map<string, float> isn't going to scale very well to other types (you'll be copy-pasting a lot of code). For comparison, see our version of readMember for std::vector in this file.

Consider re-writing this to work for a map from string to a generic value type (templated on value type).

You can make this version more generic and still do error-handling here to detect and report a failed parse of a value.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I was planning on that refactor eventually, when time permitted.

Comment thread src/esp/io/JsonStlTypes.h Outdated
if (it->value.IsFloat()) {
val.emplace(key, it->value.GetFloat());
} else {
LOG(ERROR) << "Invalid float value specified in JSON config " << tag
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Counterpoint: LOG(ERROR) fits with our existing JSON-reading convention. An assert isn't appropriate because this is a runtime validation of data, whereas asserts are to catch programmer errors in code. Also, treating the error as fatal is inappropriate (it's up to the calling JSON code to decide the severity of a failed parse; some callers may want to just have the error logged but then keep going).

Comment thread src/esp/io/JsonStlTypes.h
*/

template <>
inline bool readMember(const JsonGenericValue& d,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a comment showing what the expected JSON looks like? This will help when someone needs to come along later and write an addMember (writer) for maps.

Comment thread src/esp/physics/bullet/BulletArticulatedObject.h Outdated
Comment thread src/esp/physics/bullet/BulletRigidObject.h Outdated
Comment thread src/esp/physics/bullet/BulletURDFImporter.cpp Outdated
Comment thread src/esp/physics/bullet/BulletURDFImporter.cpp Outdated
Comment thread src/esp/sim/Simulator.cpp
Comment thread src/esp/physics/URDFImporter.cpp
@aclegg3 aclegg3 requested a review from eundersander June 16, 2021 02:44
Copy link
Copy Markdown
Contributor

@eundersander eundersander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Do not delete this pull request or issue due to inactivity.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants