RobotLocomotion / drake

Model-based design and verification for robotics.
https://drake.mit.edu
Other
3.35k stars 1.27k forks source link

VIEW URDF with joint sliders. #8913

Closed Islam0mar closed 6 years ago

Islam0mar commented 6 years ago

I wanted the feature here: Making a simple URDF in Drake.

But when I tried to use VTK I got

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff4b8f477 in vtkSmartPointerBase::~vtkSmartPointerBase() () from /usr/lib/x86_64-linux-gnu/libvtkCommonCore-6.2.so.6.2

Here is the code I used"it segfault even when I only include VTK headers, so if I removed VTK includes it works":

#include <sys/stat.h>
#include <memory>
#include "drake/common/find_resource.h"
#include "drake/common/text_logging_gflags.h"
#include "drake/lcm/drake_lcm.h"
#include "drake/multibody/joints/floating_base_types.h"
#include "drake/multibody/parsers/urdf_parser.h"
#include "drake/multibody/rigid_body_plant/drake_visualizer.h"
#include "drake/multibody/rigid_body_plant/rigid_body_plant.h"
#include "drake/systems/analysis/simulator.h"
#include "drake/systems/framework/diagram.h"
#include "drake/systems/framework/diagram_builder.h"
#include "drake/systems/primitives/constant_vector_source.h"

// vtk slider headers
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkProperty2D.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkSliderWidget.h>
#include <vtkSmartPointer.h>
#include <vtkTextProperty.h>
#include <vtkWidgetEvent.h>
#include <vtkWidgetEventTranslator.h>

#include <iostream>

// drake::systems::Simulator<double>* sim;
// Check if the specified file exists.
// @param[in] name of the file
// @return existence (true) or otherwise (false)
bool file_exists(const std::string& name) {
  struct stat buffer;
  return (stat(name.c_str(), &buffer) == 0);
}

// // This does the actual work.
// // Callback for the interaction
// class vtkSliderCallback : public vtkCommand {
//  public:
//   static vtkSliderCallback* New() { return new vtkSliderCallback; }
//   virtual void Execute(vtkObject* caller, unsigned long, void*) {
//     vtkSliderWidget* sliderWidget = reinterpret_cast<vtkSliderWidget*>(caller);
//     this->value =
//         static_cast<vtkSliderRepresentation*>(sliderWidget->GetRepresentation())
//             ->GetValue();
//     std::cout << this->value << std::endl;
//   }
//   vtkSliderCallback() : value(0) {}
//   double value;
// };

// // vtkWindow creation
// // And interface
// class my_vtkWindow {
//  public:
//   vtkSmartPointer<vtkRenderer> renderer;
//   vtkSmartPointer<vtkRenderWindow> renderWindow;
//   vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor;
//   std::vector<vtkSmartPointer<vtkSliderWidget>> sliderWidgets;
//   std::vector<vtkSmartPointer<vtkSliderCallback>> callbacks;
//   std::vector<vtkSmartPointer<vtkSliderRepresentation2D>> sliderReps;
//   my_vtkWindow() {
//     // A renderer and render window
//     renderer = vtkSmartPointer<vtkRenderer>::New();
//     renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
//     renderWindow->AddRenderer(renderer);

//     // An interactor
//     renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
//     renderWindowInteractor->SetRenderWindow(renderWindow);

//     // Render an image (lights and cameras are created automatically)
//     renderWindow->Render();
//   }
//   void addSlider(double x, double y) {
//     vtkSmartPointer<vtkSliderRepresentation2D> sliderRep =
//         vtkSmartPointer<vtkSliderRepresentation2D>::New();

//     sliderRep->SetMinimumValue(0.0);
//     sliderRep->SetMaximumValue(360.0);
//     sliderRep->SetValue(180.0);
//     sliderRep->SetTitleText("");

//     // Set color properties:
//     // Change the color of the knob that slides
//     sliderRep->GetSliderProperty()->SetColor(1, 0, 0);  // red

//     // Change the color of the text indicating what the slider controls
//     sliderRep->GetTitleProperty()->SetColor(1, 0, 0);  // red

//     // Change the color of the text displaying the value
//     sliderRep->GetLabelProperty()->SetColor(1, 0, 0);  // red

//     // Change the color of the knob when the mouse is held on it
//     sliderRep->GetSelectedProperty()->SetColor(0, 1, 0);  // green

//     // Change the color of the bar
//     sliderRep->GetTubeProperty()->SetColor(1, 1, 0);  // yellow

//     // Change the color of the ends of the bar
//     sliderRep->GetCapProperty()->SetColor(1, 1, 0);  // yellow

//     sliderRep->GetPoint1Coordinate()->SetCoordinateSystemToDisplay();
//     sliderRep->GetPoint1Coordinate()->SetValue(x, y);
//     sliderRep->GetPoint2Coordinate()->SetCoordinateSystemToDisplay();
//     sliderRep->GetPoint2Coordinate()->SetValue(x + 160, y);

//     vtkSmartPointer<vtkSliderWidget> sliderWidget =
//         vtkSmartPointer<vtkSliderWidget>::New();
//     sliderWidget->SetInteractor(renderWindowInteractor);
//     sliderWidget->SetRepresentation(sliderRep);
//     sliderWidget->SetAnimationModeToAnimate();
//     sliderWidget->EnabledOn();

//     vtkSmartPointer<vtkSliderCallback> callback =
//         vtkSmartPointer<vtkSliderCallback>::New();

//     sliderWidget->AddObserver(vtkCommand::InteractionEvent, callback);

//     sliderWidgets.push_back(sliderWidget);
//     callbacks.push_back(callback);
//     sliderReps.push_back(sliderRep);
//   }
//   void start() {
//     renderWindowInteractor->Initialize();
//     renderWindow->Render();
//     renderWindowInteractor->Start();
//   }
// };

// class mainLoopCallback : public vtkCommand {
//  public:
//   static mainLoopCallback* New() { return new mainLoopCallback; }
//   virtual void Execute(vtkObject* caller, unsigned long, void*) {
//     drake::systems::BasicVector<double> initial_conditions(n);
//     for (int i = 0; i < n; i++) {
//       initial_conditions.SetAtIndex(i, (w.callbacks[i])->value);
//     }
//     drake::systems::Context<double>& context(sim->get_mutable_context());
//     drake::systems::VectorBase<double>& state =
//         context.get_mutable_continuous_state_vector();
//     state.SetFromVector(initial_conditions.get_value());
//     sim->Initialize();
//   }
//   mainLoopCallback() {}
//   my_vtkWindow w;
//   int n;
// };

namespace drake {
int DoMain(int argc, char* argv[]) {
  lcm::DrakeLcm lcm;

  auto tree = std::make_unique<RigidBodyTree<double>>();

  std::string x;
  std::cin >> x;
  const std::string& kPendulumUrdfPath = x;

  if (!file_exists(kPendulumUrdfPath)) {
    throw std::runtime_error(std::string("could not find '") +
                             kPendulumUrdfPath + std::string("'"));
  }

  parsers::urdf::AddModelInstanceFromUrdfFileToWorld(
      kPendulumUrdfPath, multibody::joints::kFixed, tree.get());

  tree->compile();

  // Instantiate builder.
  systems::DiagramBuilder<double> builder;

  // Move double pendulum tree to plant.
  auto plant =
      builder.AddSystem<systems::RigidBodyPlant<double>>(std::move(tree));

  // Add visualizer client.
  auto visualizer = builder.AddSystem<systems::DrakeVisualizer>(
      plant->get_rigid_body_tree(), &lcm);

  // Wire all blo`cks together.
  builder.Connect(plant->get_output_port(0), visualizer->get_input_port(0));

  auto diagram = builder.Build();
  // Instantiate and configure simulator.

  systems::Simulator<double> simulator(*diagram);
  // simulator.set_target_realtime_rate(FLAGS_realtime_rate);

  systems::Context<double>& context(simulator.get_mutable_context());
  // context.FixInputPort(0, input.get_mutable_value());  // zero torque
  systems::VectorBase<double>& state =
      context.get_mutable_continuous_state_vector();
  // (theta1, theta2, theta1dot, theta2dot)
  // systems::BasicVector<double> initial_conditions(4);
  // initial_conditions.SetAtIndex(0, 1.0);
  // initial_conditions.SetAtIndex(1, 1.0);
  // initial_conditions.SetAtIndex(2, 0.0);
  // initial_conditions.SetAtIndex(3, 0.0);
  // state.SetFromVector(initial_conditions.get_value());

  simulator.Initialize();

  // vtkSmartPointer<mainLoopCallback> callback =
  //     vtkSmartPointer<mainLoopCallback>::New();
  int n = state.size();
  //callback->n = n;

  // my_vtkWindow w;
  // for (double i = 0; i < n; i++) {
  //   w.addSlider(40, i * 10 + 10);
  // }
  simulator.Initialize();
  // sim = &simulator;
  // vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
  //     vtkRenderWindowInteractor::New();
  // renderWindowInteractor->CreateRepeatingTimer(1);
  // renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, callback);
  // w.renderWindowInteractor->Start();

  // w.start();

  return EXIT_SUCCESS;
}
}  // namespace drake

int main(int argc, char* argv[]) {
  drake::DoMain(argc, argv);
  return 0;
}

I tried the VTK part in an isolated program and it worked.

cmake file:

cmake_minimum_required(VERSION 3.0)
project(VIEW_URDF)
set(CMAKE_VERBOSE_MAKEFILE true)

find_program(LSB_RELEASE lsb_release)
execute_process(COMMAND ${LSB_RELEASE} -is
    OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")

if(${LSB_RELEASE_ID_SHORT} MATCHES "Arch")
    set(drake_DIR "~/e/drake/build/install/drake/lib/cmake/drake/")
    set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
elseif(${LSB_RELEASE_ID_SHORT} MATCHES "Ubuntu")
    set(VTK_DIR "/usr/lib/cmake/vtk-6.2/VTKTargets.cmake")
    set(drake_DIR "/home/drake/build/install/drake/lib/cmake/drake/")
else()
    message("invalid")
endif()

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

find_package(drake CONFIG REQUIRED)
find_package(PythonInterp 2.7 EXACT MODULE REQUIRED)
set(PYTHONPATH "${drake_PYTHON_DIRS}:$ENV{PYTHONPATH}")

set(PROJECT_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
# Bring headers into the project
include_directories(include)
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_PATH}/bin")
set(CMAKE_BINARY_DIR "${PROJECT_PATH}/bin")

# The file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "${PROJECT_PATH}/src/*.cc")
add_executable(${PROJECT_NAME} ${SOURCES})

target_link_libraries(${PROJECT_NAME}
    drake::drake
    gflags ${VTK_LIBRARIES})

target_compile_options(${PROJECT_NAME} PUBLIC -O0 -ggdb3 -Wall)

I think adding a tab in drake-visualizer for urdf-view with sliders for intial-conditions would be great like in the video above.

Question: Why it segfault when I include VTK headers?

Thanks in advance

jwnimmer-tri commented 6 years ago

Hi @CatchMeFastFat. Please take a look at http://drake.mit.edu/getting_help.html -- we now have a StackOverflow forum for questions like this (so I will close this out -- you can repost there if you are still having trouble).

To guess at the answer, though: your error shows VTK 6 being loaded, but the Drake binary release also provides (and depends on) VTK 8. Be sure that you are not mixing and matching different versions of VTK.