Connect to gazebo using a custom socket client

asked 2019-04-18 11:58:17 -0500

kangkan gravatar image

Hi,

My goal here is to control a model in gazebo using keys from the keyboard. I was able to do that using plugins within gazebo using a publisher and subscriber pattern that sends and receives information over topics. But now I want to achieve the same by a completely independent process say using ZeroMQ that does not include any gazebo dependencies. Can you guys give me any insights to this. It will be very helpful.

Code for plugin1:

KeyboardGUIPlugin::KeyboardGUIPlugin()
  : GUIPlugin(), dataPtr(new KeyboardGUIPluginPrivate)
{
  gazebo::gui::MainWindow *mainWindow = gazebo::gui::get_main_window();
  if (!mainWindow)
  {
    gzerr << "Couldn't get main window, keyboard events won't be filtered."
        << std::endl;
    return;
  }
  mainWindow->installEventFilter(this);

  // Make this invisible
  this->move(-1, -1);
  this->resize(1, 1);

  // Initialize transport.
  // Publish the key presses to the autoCrane topic
  this->dataPtr->gzNode = transport::NodePtr(new transport::Node());
  this->dataPtr->gzNode->Init();
  this->dataPtr->keyboardPub =
      this->dataPtr->gzNode->Advertise<msgs::Any>("~/keyboard/keypress");
}

/////////////////////////////////////////////////
KeyboardGUIPlugin::~KeyboardGUIPlugin()
{
  this->dataPtr->keyboardPub.reset();
  this->dataPtr->gzNode->Fini();
}

/////////////////////////////////////////////////
// Send the message
void KeyboardGUIPlugin::OnKeyPress(const gazebo::common::KeyEvent &_event)
{
  msgs::Any msg;
  msg.set_type(msgs::Any_ValueType_INT32);
  msg.set_int_value(_event.key);
  this->dataPtr->keyboardPub->Publish(msg);
}

/////////////////////////////////////////////////  
bool KeyboardGUIPlugin::eventFilter(QObject *_obj, QEvent *_event)
{
  // Check if there was a keypress in a child
  if (_event->type() == QEvent::ShortcutOverride)
  {
    QKeyEvent *qtKeyEvent = dynamic_cast<QKeyEvent *>(_event);

    gazebo::common::KeyEvent gazeboKeyEvent;
    gazeboKeyEvent.text = qtKeyEvent->text().toStdString();

    // QKeyEvent::key() does not distiguish between lowercase and uppercase.
    // Need to use QKeyEvent::text() to get the unicode character.
    // Special keys (shift, ctrl) will have an empty text field.
    gazeboKeyEvent.key = !gazeboKeyEvent.text.empty() ? gazeboKeyEvent.text[0] :
      qtKeyEvent->key();

    this->OnKeyPress(gazeboKeyEvent);
  }
  return QObject::eventFilter(_obj, _event);
}

code for plugin2:

void KeysToJointsPlugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
{ 
  this->model = _model;
  auto controller = this->model->GetJointController();

  // Load params from SDF
  if (_sdf->HasElement("map"))
  {
    auto mapElem = _sdf->GetElement("map");
    while (mapElem)
    {
       // Get the joints from the sdf file
      auto jointName = mapElem->Get<std::string>("joint");
      auto joint = this->model->GetJoint(jointName);
      if (!joint)
      {
        // It will complain if no joints are found
        gzwarn << "Can't find joint [" << jointName << "]" << std::endl;
      }
      else
      {
        // The joint should have the below characteristics
        if (!mapElem->HasAttribute("key") ||
            !mapElem->HasAttribute("scale") ||
            !mapElem->HasAttribute("type"))
        {
          gzwarn << "Missing [key], [scale] or [type] attribute, skipping map."
              << std::endl;
          mapElem = mapElem->GetNextElement("map");
          continue;
        }
        KeyInfo info;
        info.key = mapElem->Get<int>("key");
        info.joint = joint;
        info.scale = mapElem->Get<double>("scale");
        info.type = mapElem->Get<std::string>("type");

        if (info.type != "force")
        {
          double kp = 0;
          double ki = 0;
          double kd = 0;
          if (mapElem->HasAttribute("kp"))
            kp = mapElem->Get<double>("kp");
          if (mapElem->HasAttribute("ki"))
            ki = mapElem->Get<double>("ki");
          if (mapElem->HasAttribute("kd"))
            kd = mapElem->Get<double>("kd");

          common::PID pid(kp, ki, kd);
          if (info.type == "position")
            controller->SetPositionPID(info.joint->GetScopedName(), pid);
          else if (info.type == "velocity")
            controller->SetVelocityPID(info.joint->GetScopedName(), pid);
         }

         this->keys.push_back(info);
       }

      mapElem = mapElem->GetNextElement("map");
    }
  }

  // Initialize transport
  this->node = transport::NodePtr(new transport::Node());
  this->node->Init();

  // subscribe to KeyboardGUIPlugin by registering OnKeyPress() callback ...
(more)
edit retag flag offensive close merge delete

Comments

Hi, did you solve this issue? If so, could you provide your solution or at least roughly say, how you did it?

m.bahno gravatar imagem.bahno ( 2021-11-25 09:37:41 -0500 )edit