ROS-Mobile/ROS-Mobile-Android

Multiple joysticks on the same topic don't work

Closed this issue · 6 comments

P4STA commented

Hi,

I'm trying to make a UI for controlling a 6DOF manipulator. And I thought it would be interesting to drive the rotation and translation of each axis of the manipulator with a separate joystick. Therefore I need three joysticks (X,Y,Z), each publishing two values (linear, angular). Together they would make the full 6DOF Twist message that I can use to drive my manipulator.
However, when I set up the UI with 3 joysticks and set them to publish different parts of the Twist message, only Linear Z and Angular Z is being published. Regardles of which joystick I move, all of them are publishing data for the Z axis.

Screenshot_20220419-103907
Screenshot_20220419-115001
Screenshot_20220419-115015
Screenshot_20220419-115024
Screenshot_20220419-115031

It looks to be a bug as I don't see a reason why it could not work.

Yep, thats a big problem. Just to explain this:
Each Joystick widget create its own publisher. If two of them use the same topic name, one of them discards the other. It's only possible with ROS2 but there is also some kind of priority involved..

You could for example create an additional node which combines all the latest values from your 3 topics into one Twist message.

Okay, this would be one of the simplest solution I came up with:

#! /usr/bin/env python

import rospy
from geometry_msgs.msg import Twist


def msgCallback(inputMsg: Twist):
    if inputMsg.linear.x:
        outputMsg.linear.x = inputMsg.linear.x

    if inputMsg.linear.y:
        outputMsg.linear.y = inputMsg.linear.y

    if inputMsg.linear.z:
        outputMsg.linear.z = inputMsg.linear.z

    if inputMsg.angular.x:
        outputMsg.angular.x = inputMsg.angular.x

    if inputMsg.angular.y:
        outputMsg.angular.y = inputMsg.angular.y

    if inputMsg.angular.z:
        outputMsg.angular.z = inputMsg.angular.z

    publisher.publish(outputMsg)


if __name__ == "__main__":
    outputMsg = Twist()

    rospy.init_node('combiner', anonymous=True)

    subscriber1 = rospy.Subscriber("/twistX", Twist, msgCallback)
    subscriber2 = rospy.Subscriber("/twistY", Twist, msgCallback)
    subscriber3 = rospy.Subscriber("/twistZ", Twist, msgCallback)
    publisher = rospy.Publisher("/twist", Twist, queue_size=10)

    rospy.spin()

Please dont judge me on that... :D

So basically this node subscribes to all of your three joystick topics, which you have to change, and republish the combination via another topic (here "/twist", but of cause you can name however you like).

P4STA commented

Thanks, I will use the workaround.
I didn't realize multiple publishers on the same topic will be overriding each other.

Edit: By the way :D The callback could be just like this

def msgCallback(msg):
    publisher.publish(msg)

Regarding your edit:
I think you are not right, because only the values of the individual topics have to be copied to the tmp message if their not zero. Otherwise, you wouldnt get any benefits besides three times the message amount and a lot of zeros ^^

P4STA commented

Oh, I guess you're right. I haven't considered controlling multiple joystick at once, so in my case the simplification works just fine. I have already implemented it this way withou issues. But yes, If I wanted to use more joysticks at once your solution is better.

I hope I was able to help you. I will close the issue, but feel free to open it again if you continue to have problems with that :)