Razer Hydra - modulabs/gazebo-tutorial GitHub Wiki

Introduction

Gazebo๋Š” Razer Hydra ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชจ์…˜ ๋ฐ ๋ฐฉํ–ฅ ๊ฐ์ง€ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Gazebo์—์„œ ๋ชจ๋ธ๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Razer hydra ์ปจํŠธ๋กค๋Ÿฌ๋Š” 6์ž์œ ๋„ VR ์ปจํŠธ๋กค๋Ÿฌ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์˜ค๋ž˜๋œ ์ปจํŠธ๋กค๋Ÿฌ๋ผ ๋‹ค๋ฅธ ๊ธฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

Razer Hydra configuration.

ํ„ฐ๋ฏธ๋„ (CTRL-ALT-T)์„ ์—ด๊ณ  ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

echo -e "ATTRS{idProduct}=="0300",ATTRS{idVendor}=="1532",ATTR{bInterfaceNumber}=="00",TAG="hydra-tracker"\nSUBSYSTEM=="hidraw",TAGS=="hydra-tracker", MODE="0666", SYMLINK+="hydra"" > 90-hydra.rules

๊ทธ๋Ÿฌ๋ฉด 90-hydra.rules๋ผ๋Š” ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๋ฃจํŠธ ์•ก์„ธ์Šค์—†์ด ์ปจํŠธ๋กค๋Ÿฌ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

sudo cp 90-hydra.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules

Gazebo compilation with Razer Hydra support.

optional libusb dependecy๋ฅผ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

sudo apt-get install libusb-1.0-0-dev

Hydra๊ฐ€ ๊ตฌ์„ฑ๋˜๊ณ  ์ถ”๊ฐ€ ์ข…์†์„ฑ์ด ๋งŒ์กฑ๋˜๋ฉด Hydra ์ง€์› ์†Œ์Šค์—์„œ Gazebo๋ฅผ ์ปดํŒŒ์ผ ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Gazebo๋ฅผ ์ปดํŒŒ์ผํ•˜๋ ค๋ฉด์ด ์ง€์‹œ ์‚ฌํ•ญ์„ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค. cmake ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ SDK๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ์Œ์„ ํ™•์ธํ•˜๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

-- Looking for libusb-1.0 - found. Razer Hydra support enabled.

Using Hydra within Gazebo.

๊ฐ€์ œ๋ณด์—์„œ ํžˆ๋“œ๋ผ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‘ ๋‹จ๊ณ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ์›”๋“œ ํŒŒ์ผ์— Hydra ํ”Œ๋Ÿฌ๊ทธ์ธ์„๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ฃผ์ œ์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ž๋™์œผ๋กœ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. ~/hydra.

๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” hydra ์ฃผ์ œ๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ํฅ๋ฏธ๋กœ์šด ๊ฒƒ์„ ๋งŒ๋“œ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” Hydra์˜ ์˜ค๋ฅธ์ชฝ ์กฐ์ด์Šคํ‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ฒด๋ฅผ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. HydraDemoPlugin์€ Gazebo์˜ plugins / ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Plugin code:

#include <boost/bind.hpp> #include <gazebo/gazebo.hh> #include <gazebo/physics/physics.hh> #include "gazebo/transport/transport.hh" #include "HydraDemoPlugin.hh"

using namespace gazebo;

GZ_REGISTER_MODEL_PLUGIN(HydraDemoPlugin)

///////////////////////////////////////////////// HydraDemoPlugin::HydraDemoPlugin() { }

///////////////////////////////////////////////// HydraDemoPlugin::~HydraDemoPlugin() { }

///////////////////////////////////////////////// void HydraDemoPlugin::OnHydra(ConstHydraPtr &_msg) { boost::mutex::scoped_lock lock(this->msgMutex); this->hydraMsgPtr = _msg; }

///////////////////////////////////////////////// void HydraDemoPlugin::Load(physics::ModelPtr _parent, sdf::ElementPtr /_sdf/) { // Get the world name. this->model = _parent; this->world = this->model->GetWorld();

// Subscribe to Hydra updates by registering OnHydra() callback. this->node = transport::NodePtr(new transport::Node()); this->node->Init(this->world->GetName()); this->hydraSub = this->node->Subscribe("~/hydra", &HydraDemoPlugin::OnHydra, this);

// Listen to the update event. This event is broadcast every // simulation iteration. this->updateConnection = event::Events::ConnectWorldUpdateBegin( boost::bind(&HydraDemoPlugin::Update, this, _1)); }

///////////////////////////////////////////////// void HydraDemoPlugin::Update(const common::UpdateInfo & /_info/) { boost::mutex::scoped_lock lock(this->msgMutex);

// Return if we don't have messages yet if (!this->hydraMsgPtr) return;

// Read the value of the right joystick. double joyX = this->hydraMsgPtr->right().joy_x(); double joyY = this->hydraMsgPtr->right().joy_y();

// Move the sphere. this->model->SetLinearVel(math::Vector3(-joyX * 0.2, joyY * 0.2, 0));

// Remove the message that has been processed. this->hydraMsgPtr.reset(); }

Gazebo๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ๋ชจ๋ธ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์›”๋“œ ํŒŒ์ผ์— ํฌํ•จ์‹œ์ผœ์•ผํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ํŠœํ† ๋ฆฌ์–ผ์˜ ์ „์ฒด ์„ธ๊ณ„ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค (world / hydra_demo.world์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ).

<!-- A ground plane -->
<include>
  <uri>model://ground_plane</uri>
</include>

<!-- A global light source -->
<include>
  <uri>model://sun</uri>
</include>

<!-- Load the plugin for Razer Hydra -->
<plugin name="hydra" filename="libHydraPlugin.so">
  <pivot>0.04 0 0</pivot>
  <grab>0.12 0 0</grab>
</plugin>

<!-- A sphere controlled by Hydra-->
<model name="sphere">
  <pose>0 0 0 0 0 0</pose>
  <link name="link">
    <collision name="collision">
      <geometry>
        <sphere>
          <radius>0.5</radius>
        </sphere>
      </geometry>
    </collision>
    <visual name="visual">
      <geometry>
        <sphere>
          <radius>0.5</radius>
        </sphere>
      </geometry>
    </visual>
  </link>

  <plugin name='sphere_ctroller' filename='libHydraDemoPlugin.so'></plugin>

</model>

๊ฐ€์ œ๋ณด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํžˆ๋“œ๋ผ์˜ ์˜ค๋ฅธ์ชฝ ์กฐ์ด์Šคํ‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋ฅผ ์›€์ง์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค. ํžˆ๋“œ๋ผ ํ”Œ๋Ÿฌ๊ทธ๋ฅผ ์žŠ์ง€ ๋ง๊ณ  ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์‹ญ์‹œ์˜ค.

gazebo worlds/hydra_demo.world

โš ๏ธ **GitHub.com Fallback** โš ๏ธ