lcm-proj / lcm

Lightweight Communications and Marshalling
GNU Lesser General Public License v2.1
944 stars 385 forks source link

Make udpm loopback configurable? #477

Open robclarkoi opened 8 months ago

robclarkoi commented 8 months ago

In some of my LCM applications it would be beneficial to not receive my own messages (udpm transport).

It looks like the code has been written to specifically enable this behaviour. Is there any appetite to make it (or accept PRs that make it) configurable?

Or does anyone have a suggestion as to how I can do this without modifying lcm itself? My target language/platform is c++ on Ubuntu 18.04/22.04.

ihilt commented 7 months ago

In some of my LCM applications it would be beneficial to not receive my own messages (udpm transport).

How is this happening? Could you explain a bit more about your setup or provide a minimal-reproducible-example?

robclarkoi commented 7 months ago

Thanks for your reply.

A minimal example is:

#include "exlcm/example_t.hpp"

#include <lcm/lcm-cpp.hpp>

#include <iostream>
using namespace std;

class handler_t
{
    public:
    void handleMessage(const lcm::ReceiveBuffer *, const std::string &chan, const exlcm::example_t *msg)
    {
        cout << "Received Message on Channel: " << chan << endl;

        cout << "Name: " << msg->name << endl;
    }
};

int main ()
{
    cout << "LCM loopback test" << endl;

    lcm::LCM lcm;

    if (!lcm.good())
    {
        cout << "LCM unhappy" << endl;
        return 1;
    }
    else
    {
        cout << "LCM Started" << endl;
    }

    handler_t handler;

    lcm.subscribe("TEST_CHANNEL", &handler_t::handleMessage, &handler);

    exlcm::example_t msg;

    msg.name = "Message 1";

    lcm.publish("TEST_CHANNEL", &msg);

    cout << "Published Message" << endl;

    while (0 == lcm.handle()) {}

    return 0;
}

with the result:

LCM loopback test
LCM Started
Published Message
Received Message on Channel: TEST_CHANNEL
Name: Message 1

But this is expected isn't it? It makes sense for most applications but this particular application will bridge between LCM and something else. I convert messages from the other system into LCM and visa-versa. The problem is I cannot subscribe to '.*' in LCM because I receive my own proxied messages and end up sending them back to the other system.

robclarkoi commented 7 months ago

By the time the callback is triggered I don't have access to any information about it's source do I? Otherwise I would filter it there.

ihilt commented 7 months ago

Sorry for taking so long to respond.

If I'm understanding your setup (and I may not be), there may be a way to do this with channels. If you have a setup where non-LCM system A needs to send to LCM system B through a proxy, then you could do this.

  1. System A sends non-LCM messages to the proxy.
  2. The proxy converts these messages to LCM and publishes them to channel X, which it is not subscribed to.
  3. System B is subscribed to channel X and receives these messages.

If it also needs to go the other way, i.e. system B needs to send back to system A, then you will probably want to setup an additional channel for system B to publish to, which the proxy will subscribe to.

  1. System B publishes LCM messages to channel Y.
  2. The proxy is subscribed to channel Y so it receives these messages.
  3. It forwards these onto non-LCM system A.

I haven't tested this setup so I'm not confident it will solve your problem. There may be other ways to solve this, e.g. using different IP:PORT configurations for the various systems.