Home > Software engineering >  Scalar conversion (from double to AutoDiffXd) failed with Drake binary
Scalar conversion (from double to AutoDiffXd) failed with Drake binary

Time:05-04

I am trying to get MultibodyPlant<drake::AutoDiffXd> from MultibodyPlant<double> using the C code:

#include <drake/multibody/parsing/parser.h>
#include <drake/multibody/plant/multibody_plant.h>

int main() {
  const std::string sdf_file = "../split_pendulum.sdf";
  drake::multibody::MultibodyPlant<double> plant(0.1);
  drake::multibody::Parser(&plant).AddModelFromFile(sdf_file);
  plant.Finalize();
  std::unique_ptr<drake::multibody::MultibodyPlant<drake::AutoDiffXd>>
      plant_ad = drake::systems::System<double>::ToAutoDiffXd(plant);
}

The code can pass compile (with Drake v1.2.0 binary, macOS Monterey) but run with error, and print message:

libc  abi: terminating with uncaught exception of type std::logic_error: System ::_ of type drake::multibody::MultibodyPlant<double> does not support scalar conversion to type drake::AutoDiffXd

I found the error came from the function ToAutoDiffXd(). How can I properly get MultibodyPlant<drake::AutoDiffXd>?

Note I also add a example in drake source code which directory is drake/examples/mutibody/cart_pole/mbp_ad.cc:

#include "drake/common/find_resource.h"
#include "drake/multibody/parsing/parser.h"
#include "drake/multibody/plant/multibody_plant.h"

int main() {
  const std::string full_name = drake::FindResourceOrThrow(
      "drake/examples/multibody/cart_pole/cart_pole.sdf");
  drake::multibody::MultibodyPlant<double> plant(0.1);
  drake::multibody::Parser(&plant).AddModelFromFile(full_name);
  plant.Finalize();
  std::unique_ptr<drake::multibody::MultibodyPlant<drake::AutoDiffXd>>
      plant_ad = drake::systems::System<double>::ToAutoDiffXd(plant);
}

add add following code in file drake/examples/mutibody/cart_pole/BUILD.bazel

drake_cc_binary(
     name = "mbp_ad",
     srcs = ["mbp_ad.cc"],
     add_test_rule = 1,
     data = ["cart_pole.sdf"],
     deps = [
         "//common:find_resource",
         "//multibody/parsing",
         "//multibody/plant",
     ],
)

Finally, This code of example can pass compile and run correct using Drake source code.

CodePudding user response:

Have you changed split_pendulum.sdf? The following code runs fine for me (admittedly, I've only tested so far on ubuntu and the master branch):

// https://stackoverflow.com/questions/72108736/scalar-conversion-from-double-to-autodiffxd-failed-with-drake-binary
GTEST_TEST(MultibodyPlantTest, StackOverflow72108736) {
  drake::multibody::MultibodyPlant<double> plant(0.1);
  Parser(&plant).AddModelFromFile(
      FindResourceOrThrow("drake/multibody/plant/test/split_pendulum.sdf"));
  plant.Finalize();
  std::unique_ptr<drake::multibody::MultibodyPlant<drake::AutoDiffXd>>
      plant_ad = drake::systems::System<double>::ToAutoDiffXd(plant);
}

Notice that I'm using Drake's version of split_pendulum, and your code looks like it's using a local copy/edit?

CodePudding user response:

Drake's scalar conversion support (such as ToAutoDiffXd) relies on C run-time type information (RTTI). It's possible that a build system problem (such as violating ODR -- the One Definition Rule) would lead to this result.

That build system bug could be a defect in Drake, or in your own build code.

For the failing case "macOS Monterey using Drake v1.2.0 binary, runs Failed", could you please share exactly how you compile the binary? What build files, and what build commands are being used?

  • Related