I am trying to use drake within the class of our code. I have declared the drake variables within the class. For this purpose, I initialized the drake variables within header files as
drake::systems::DiagramBuilder<double> builder_;
std::unique_ptr< MultibodyPlant< double > plant_;
drake::multibody::MultibodyPlant<double>* plant_{};
drake::geometry::SceneGraph<double>* scene_graph_{};
std::unique_ptr<drake::systems::Diagram<double>> diagram_;
std::unique_ptr<drake::systems::Context<double>> diagram_context_;
drake::systems::Context<double> *plant_context_;
std::unique_ptr<drake::systems::Simulator<double>> simulator_;
double timestep_;
double time_;
In the source file, I have initialized them as follow
drake::multibody::MultibodyPlantConfig plant_config;
plant_config.time_step = 1e-3;
std::tie(plant_, scene_graph_) = AddMultibodyPlant(plant_config,&builder_);
const std::string urdf = drake::FindResourceOrThrow("drake/urdf/iiwa_description/urdf/iiwa14_no_collision.urdf");
drake::multibody::Parser(plant_).AddModelFromFile(urdf);
const double static_friction = 0.5;
const Eigen::Matrix<double, 4, 1> green(0.5, 1.0, 0.5, 1.0);
plant_->RegisterVisualGeometry(plant_->world_body(), drake::math::RigidTransformd(),
drake::geometry::HalfSpace(), "GroundVisualGeometry", green);
// // For a time-stepping model only static friction is used.
const drake::multibody::CoulombFriction<double> ground_friction(static_friction,
static_friction);
plant_->RegisterCollisionGeometry(plant_->world_body(), RigidTransformd(),
drake::geometry::HalfSpace(),
"GroundCollisionGeometry", ground_friction);
Vector3d gravity;
gravity << 0.0, 0.0, -9.81;
plant_->mutable_gravity_field().set_gravity_vector(gravity);
plant_->WeldFrames(plant_->world_frame(), plant_->GetFrameByName("base"));
plant_->Finalize();
plant_->set_penetration_allowance(1e-3);
plant_->set_stiction_tolerance(1e-3);
// Publish contact results for visualization.
drake::visualization::AddDefaultVisualization(&builder_);
diagram_ = builder_.Build();
// // Create a context for this system:
diagram_context_ = diagram_->CreateDefaultContext();
drake::systems::Context<double>& plant_context = diagram_->GetMutableSubsystemContext(*plant_, diagram_context_.get());
plant_context_ = &(diagram_->GetMutableSubsystemContext(*plant_, diagram_context_.get()));
Eigen::VectorXd tau = Eigen::VectorXd::Zero(plant_->num_actuated_dofs());
plant_->get_actuation_input_port().FixValue(plant_context_, tau);
simulator_ = std::make_unique<drake::systems::Simulator<double>>(*diagram_, std::move(diagram_context_));
simulator_->set_publish_every_time_step(true);
simulator_->set_target_realtime_rate(1.0);
simulator_->Initialize();
timestep_ = 1e-3;
time_ = timestep_;
simulator_->AdvanceTo(time_);
Now it runs fine when simulator_->AdvanceTo(time_) is called within initializer. However, when I try to call simulator_->AdvanceTo(time_) within a callback function (where simulator_ is defined and is visible within the class function), it gives the following error
abort: Failure at geometry/meshcat.cc:606 in ThrowIfWebsocketThreadExited(): condition 'IsThread(main_thread_id_)' failed.
I looked at the code but it do not give much information why the websocketthread is dying. Any help and guidance will be highly appreciated.
The error message is saying that you tried to call the meshcat API from a different thread than the thread which created the meshcat instance. The meshcat class does some nontrivial data sharing with a networking thread, so we currently restrict that the meshcat API is only used from a single thread.