VirtualBox XBox360 ROS Control Over Network

This post may be considered a continuation of another post, "Use an Xbox controller over Vagrant with Mac". In fact, the the post talks nothing about setting up the Xbox controller with the VM. What I've built on top of that is the ability to communicate with the controller from that VM with a ROS master setup across a wired switch, and all the problems that came along with that.

The Hardware

  • Xbox360 wired controller
  • Odroid C1+
  • TP-LINK TL-SG1005D switch
  • Ugreen 20258 USB 3.0 to ethernet adaptor
  • Mac

The Hardware Setup

Both the Mac and Odroid plug into the switch, and the controller plugs into the Mac. This setup is meant to simulate the situation where the switch resides inside the AUV, connecting the three computers, as well as providing an external ethernet port. In order to teleoperate the AUV, one would tether it to their laptop. The Xbox360 controller, connected to the laptop, is just a nice control interface.

The ethernet adaptor requires drivers, and possibly a reboot, but then it connected fine. Make sure to follow the manufacturer install instructions because there are a few nuances. Setting the connection for the device is not completely straightforward either. When you find the device in your network settings, it will give you the option of four IPv4 connection modes--  Using DHCP, Using DHCP with manual address, Using BootP, and Manually. I chose "Manually", and for ease of switching between networks, I put the device on the same subnet as my wireless network, with subnet mask 255.255.255.0. That might not be the best idea from a networking standpoint, but it lets me give the Odroid access to the internet, when necessary. The same goes for the VM. Perhaps related to this (but I don't think so), the adaptor loses its manual IP address every so often. I suspect this has something to do with OS X keeping the adapter driver daemon alive in the background when it's not active. When this occurs, I set the device's IP to a different address in network settings, prompting the adaptor driver to wake up and assign the new IP.

ROS Over Multiple Machines

As I mentioned before, the software setup for controlling an Xbox360 controller from a Vagrant-managed VirtualBox VM can be found in this post.

By default, VirtualBox VMs access the external network via Network Address Translation (NAT). This method essentially creates a private, routed network within the VM, albeit inaccessible from the rest of the world, even the host computer except by default pathways. Additionally, vagrant establishes an exception for SSH connections. Without getting into all the options (read more about them here), you want to change your VMs networking mode to Bridged, by adding the following to your Vagrantfile:

config.vm.network :public_network, ip: "<chosen VM IP>", :public_network => "<network interface>"

For example, I use:

config.vm.network :public_network, ip: "192.168.1.99", :public_network => "en5: AX88179 USB 3.0 to Gigabit Ethernet"

You could leave off everything after the comma. In that case, vagrant will prompt you for the network interface when you vagrant reload. In Bridged network mode, the VM attaches itself to a device driver for a network interface, using it to communicate with any networks accessible to that interface. Once this connection is set, vagrant reload your machine, and follow the connectivity test instructions for ROS across multiple machines to ensure that you do indeed have that functionality.

Note that before you finally turn everything on, you must tweak a few odds and ends:

  • Disconnect your Xbox360 controller and don't reconnect it until you're SSHed into your VM
  • On your remote machine:
    • Run roscore and take note of the "ROS_MASTER_URI=..." line. You'll set this environment variable, exactly as you see it here, for both machines communicating.
    • export ROS_IP=<this machine IP>
    • export ROS_MASTER_URI=http://<this machine IP>:<roscore port>
  • Once inside your VM, set the following environment variables. Take note that the ROS_IP IP is that of the VM, while the IP and port for the ROS_MASTER_URI comes from the startup output from the machine on which you ran `roscore`.
    • export ROS_IP=<your VM IP>
    • export ROS_MASTER_URI=http://<roscore machine IP>:<roscore port>

Once you start your roscore on your ROS master machine, start the joystick node on the other. rostopic echo /joy on the ROS master to see messages come back from the controller while you fiddle with it.