Home | Tutorials | Wiki | Issues
Ask Your Question
1

How to communicate with GZServer over a custom Socket-Client

asked 2016-05-18 09:17:36 -0500

TwoBid gravatar image

updated 2016-06-01 02:54:00 -0500

Hi Gazebo Community,

I have to publish some gazebo data to a windows application. For that I wanted to establish a socket communication. I generated a model plugin that is publishing data of interest. The data I can readout through the gazebo gui. For the next step I wanted create a standalone socket client to read the data published by gazebo. As a starter for socket communication the result confuses me.

Code for Client:

using namespace std;

int main(int argc, char* argv[])
{
    int client;
    int portNum = 11345; // NOTE that the port number is same for both client and server
    bool isExit = false;
    int bufsize = 1024;
    char buffer[bufsize];
    char* ip = "127.0.0.1";

    struct sockaddr_in server_addr;

    /// \brief Creating a new Socketconnection
    /// \param[ARG 1] Adress Domain of the Socket
    /// \param[ARG 2] Type of the Socket. Continous TCP Stream
    /// \param[ARG 3] Protocol, choosen by the OS
    client = socket(AF_INET, SOCK_STREAM, 0);

    if(client < 0){
        cerr << "\nError establishing socket..." << endl;
        exit(1);
    }

    cout << "\n=> Client has been created..." << endl;

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(portNum);
    server_addr.sin_addr.s_addr = inet_addr(ip);

    // Connecto to the Socket-Server
    if( connect( client, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 ){
        cerr << "\nError establishing connection to Server..." << endl;
        exit(1);
    }
    cout << "=> Awaiting confirmation from the server..." << endl;
    recv(client, buffer, bufsize, 0);
    cout << "=> Connection confirmed..." << endl;


    do {
        recv(client, buffer, bufsize, 0);
        cout << buffer << " ";
    } while (true);

    cout << endl;
    cout << "\n=> Connection terminated.\nGoodbye...\n";
    close(client);

    return 0;
}

And the output is the following:

=> Client has been created...
=> Awaiting confirmation from the server...
=> Connection confirmed...
00000048

����؁�:topic_namepaces_init#
default
/gazebo
velodyne_hdl-3200000990

�������:publishers_init�
K
/gazebo/default/pose/local/infogazebo.msgs.PosesStamped
10.12.0.62 ��
E
/gazebo/default/pose/infogazebo.msgs.PosesStamped
10.12.0.62 ��
6
/gazebo/default/guigazebo.msgs.GUI
10.12.0.62 ��
@
/gazebo/default/responsegazebo.msgs.Response
10.12.0.62 ��
J
/gazebo/default/world_statsgazebo.msgs.WorldStatistics
10.12.0.62 ��
?
/gazebo/default/model/infogazebo.msgs.Model
10.12.0.62 ��
A

I assumed a stream of data and not one single output. Is it right what I'm seeing? How can I access for example the custom topic: /gazebo/veldoyne/scan_pose? Is that because I'm not encoding the ProtoBuf message in the right way and should I proceed with ign_transport lib to create a windows socket client for reading gazebo data?

Thanks for every advice.

Cheers, Rob

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
1

answered 2016-05-24 12:39:11 -0500

Carlos Agüero gravatar image

What you're seeing makes sense to me. You're probably observing the internal encoding of one or more Gazebo Transport messages, plus the internal encoding of a protobuf message. It would help if you post the publisher side too.

I'd suggest to create a subscriber on your Gazebo plugin and make sure that you get the data you're interested in your subscriber callback. Once you're sure that you're receiving the data correctly, you have to forward that data to your Windows process. I see two options:

  • You can create your custom protocol to send the data based on raw sockets. This is super flexible but probably more error-prone if you're not familiar with sockets. If you're using TCP, you have to make sure that the consumer process on your Windows machine knows the same protocol. Remember that TCP sockets don't preserve message boundaries. You could send two different messages on your Gazebo plugin and receive a single one on your Windows machine, for example. Alternatively, you can use UDP that doesn't have this "feature".

  • You can use a portable library. I'd recommend ZeroMQ if you still want to use a low level socket library. ZeroMQ solves the framing for you. Another approach would be to use Ignition Transport, a higher level approach that we're starting to use inside Gazebo.

edit flag offensive delete link more
0

answered 2016-05-25 02:45:54 -0500

TwoBid gravatar image

updated 2016-10-04 07:53:18 -0500

*Thanks for the reply! After a more detailed research I also started with Ignition Transport. Awesome approach and would totally fit my requirements when the windows side is also working.

[UPDATE]

Hi everyone,

I thought that it's maybe interesting how I worked out my Solution. So here my update:

In the end I decided to work with 0MQ in combination with protobuf. I have to communicate on the windows side with multiple programs, some written in c++(the robot controller) and some written in C#(database and other stuff). Because of multiple language bindings, 0MQ & protobuf are perfect for that and easy to implement. The learning curve is pretty high because of the well written api and very good documentation. I used mainly the pub/sub pattern because I have to deal with continuously changing data and that is working basically out of the box. So for me it worked out pretty good, thanks again for all advices.

Greets from Aachen

Here some snippets. I'm always open for improvements, the plugin is causing an error when the model is deleted from the world:

[ Bug Fixes :]

  • Model is now deletable without crashing gazebo
  • Threads are joined when plugin is detached
  • Signals are working now

socket_com.hpp socket_com.cpp

Deps: libzmq3-dev & includes are {zhelpers.hpp, zmq.hpp}

edit flag offensive delete link more

Comments

Could you tell me how you installed Ignition Transport? Compile from source, from debs, ... If you install from debs, which package did you install?

Carlos Agüero gravatar imageCarlos Agüero ( 2016-05-25 11:37:01 -0500 )edit

Hey Carlos, thanks for the help. I installed the deps: Package: libignition-transport-dev Status: install ok installed Section: libdevel Installed-Size: 220 Architecture: amd64 Multi-Arch: same Source: ignition-transport Version: 1.2.0-2~trusty Replaces: libignition-transport-dev (<< 0.9.0) Depends: libignition-transport (= 1.2.0-2~trusty), uuid-dev, libzmq3-dev (>= 3.0.0) Breaks: libignition-transport-dev (<< 0.9.0)

TwoBid gravatar imageTwoBid ( 2016-05-26 05:19:54 -0500 )edit

After some time I installed all the other deps with apt-get install libignition*. Then the proto file was accepted. But now the Publish() method complains about that the message type is not right. I opened an issue for that topic: https://bitbucket.org/ignitionrobotics/ign-transport/issues/41/publisher-subscriber-example

TwoBid gravatar imageTwoBid ( 2016-05-26 05:23:20 -0500 )edit

@TwoBid, were you successful in using 0MQ inside your plugin? I'm walking the same path but I'm a C/C++ newbie. Could you share some snippets if you got it working? Thanks!

traut gravatar imagetraut ( 2016-09-20 14:51:23 -0500 )edit
Login/Signup to Answer

Question Tools

2 followers

Stats

Asked: 2016-05-18 09:17:36 -0500

Seen: 1,069 times

Last updated: Oct 04 '16