ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Can I call ROS “ros::init(…)” within the player (Player/Stage) driver?

asked 2012-07-24 06:32:18 -0500

updated 2012-07-24 07:48:01 -0500

joq gravatar image

I am trying to write a Player driver that will publish messages on ROS.

Player driver does not create an executable file and hence I am not sure how to call ROS initialize within the player driver.

The main function of player driver looks like this...

void PlayerDriver::Main() 
{

int argc; // Player Main() method does not take argument 
char **argv; // What to do with argc and argv??

geometry_msgs::Point commandInput;
ros::init(argc, argv, "Command");

ros::NodeHandle n;
ros::Publisher command_pub = n.advertise<geometry_msgs::Point>("servocommand", 1000);
ros::Rate loop_rate(1);

while (ros::ok())
{


ros::spinOnce();   

ProcessMessages();

//Do some stuff
commandInput.x = globalVel.v;
commandInput.y = globalVel.w;
commandInput.z = 0.0;
command_pub.publish(commandInput);

//Do some stuff

loop_rate.sleep();
}

}

The Player driver compiles and creates a shared library and I have a cfg file. It is called by "player playerdriver.cfg" and works fine, gets connected to a Player Client but it does not publish messages on ROS.

As the Player Main() method does not take arguments, I believe this is where I am doing some mistake. Any suggestions are welcome.

edit retag flag offensive close merge delete

Comments

Thanks @allenh1 for the reply. I saw your example, Robot class. I think here the Player is a client. I am trying to create a Player server. Do you think I can create a class as you have suggested? I have had no problem integrating a player client with ROS publisher/subscriber.

sks gravatar image sks  ( 2012-07-24 07:18:22 -0500 )edit

Hm. When you say player server, what exactly do you mean?

allenh1 gravatar image allenh1  ( 2012-07-24 07:39:04 -0500 )edit

Player server (also known as Player Plugin). Please see following link http://psurobotics.org/wiki/index.php?title=Writing_a_Player_Plugin

sks gravatar image sks  ( 2012-07-24 07:44:05 -0500 )edit

Oh. I think I see what you're doing now. You're writing a Player, ROS driver to publish ros messages into player, right?

allenh1 gravatar image allenh1  ( 2012-07-24 07:47:32 -0500 )edit

What I am trying to write is this "Simulated Robot with Player driver" which will allow a player client to subscribe with Position2d. The client can send Position2d msgs to simulated robot. Now, I want to put ROS Publisher in this "simulated player robot". Hope I was able explained my problem.

sks gravatar image sks  ( 2012-07-24 08:01:14 -0500 )edit

2 Answers

Sort by » oldest newest most voted
0

answered 2012-07-24 07:46:41 -0500

joq gravatar image

updated 2012-07-24 07:50:48 -0500

There are several approaches to using a player driver in ROS:

  1. Wrapping the player library in a ROS node (like erratic_player does).

  2. Converting the driver to ROS manually.

The first probably gets the job done quicker, but is harder to maintain. With a little practice, the second is relatively straightforward. I've done quite a few. If you have follow-up questions, feel free to ask.

When converting a player driver to a ROS node, the class inherited from the player Driver class is no longer needed and just adds unnecessary complexity.

Make a simple C++ main program, something like this:

int main(int argc, char** argv)
{
  ros::init(argc, argv, NODE);
  ros::NodeHandle node;

  // topics to read and write
  brake_cmd = node.subscribe("cmd", 10, ProcessCommand,
                             ros::TransportHints().tcpNoDelay(true));
  brake_state = node.advertise<art_brake::State>("state", 10);

  if (GetParameters() != 0)             // from the player constructor
    return 1;

  ros::Rate cycle(20.0);                // set driver cycle rate

  if (Setup() != 0)                     // from the player Setup()
    return 2;

  // Main loop; grab messages off our queue and republish them via ROS
  while(ros::ok())
    {
      ...                               // activities from player Main()
      cycle.sleep();                    // sleep until next cycle
    }

  Shutdown();

  return 0;
}
edit flag offensive delete link more

Comments

Ok, what I am trying to do is exactly same as erratic_player ...however, at a smaller scale, as I have no sensors, just Position2d interface. An easier method will help but I am also looking at erratic_player.cpp to find solution.

sks gravatar image sks  ( 2012-07-24 08:07:25 -0500 )edit

The robot driver is in ROS but the client controller is written using player for an old robot. I am just taking a short-cut by not writing the client controller again using ROS. Instead I am writing this "erratic_Player" type driver to use position2dmsgs from player client and publish for ROS robot.

sks gravatar image sks  ( 2012-07-24 08:24:20 -0500 )edit

Why not just convert the client controller to ROS? Do you need to maintain both versions?

joq gravatar image joq  ( 2012-07-24 09:39:41 -0500 )edit

I might have to spend a lot of time to convert client controller to ROS. Initially I was trying the same, but its a large code written by someone else in my lab. I thought writing a player driver will be an easier task. Is there a way to email you my driver? Can you look at my code?

sks gravatar image sks  ( 2012-07-24 09:53:04 -0500 )edit

From your example, what i am getting is I can create an object of PlayerDriver class inside a small ros publisher subscriber program and call its methods in a sequence that Player will follow? Am I correct?

sks gravatar image sks  ( 2012-07-24 10:02:52 -0500 )edit

I think so, but that class would not be derived from PlayerDriver.

joq gravatar image joq  ( 2012-08-03 12:31:14 -0500 )edit
0

answered 2012-07-24 06:46:04 -0500

allenh1 gravatar image

updated 2012-07-24 07:28:36 -0500

I suggest you create a player class and take the main method out of it. This way, you can instantiate a new robot and use it as a variable in a ROS class.

What I mean:

First class:

  • PlayerLaser (inherits player)
    • starts player (from inherited methods)
    • has laser messages (now laser is an object)

Second class:

  • RosLaser
    • Has methods to get laser data.
    • Has a return method
  • In your main method (separate entity):
    • create a ROS publisher
    • create a Robot (or PlayerLaser)
    • have a RosLaser::getLaserMessage() function that returns the ROS laser type
    • publish the method

There are some examples with a player class on my github. As for a ROS class, look here.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2012-07-24 06:32:18 -0500

Seen: 791 times

Last updated: Jul 24 '12