Skip to content

Commit

Permalink
improved networking
Browse files Browse the repository at this point in the history
  • Loading branch information
Anqi Xu committed Sep 24, 2018
1 parent 9a3d50c commit aba20f4
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 19 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ Parameters:
* `$ rosdep install tello_driver`
* `$ catkin build tello_driver`

Optionally, install the [following udev rules](https://github.com/anqixu/sixad_rumble/blob/master/misc/10-gamepads.rules) for PS3 gamepads; see instructions in comments on top of file.


## Running the driver

* turn on drone and wait for its front lights to blink amber
Expand Down
2 changes: 1 addition & 1 deletion launch/logger.launch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<launch>
<arg name="bag.name" default="/home/mimic/tello"/>
<arg name="bag.name" default="$(env HOME)/tello"/>
<arg name="bag.topics" default="
/diagnostics
/joy
Expand Down
13 changes: 7 additions & 6 deletions launch/tello_node.launch
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<?xml version="1.0"?>
<launch>
<arg name="tello_ip" default="192.168.10.1" />
<!-- arg name="tello_ip" default="172.17.0.2" / -->
<arg name="tello_cmd_port" default="8889" />
<arg name="client_port" default="8890" />
<arg name="tello_cmd_server_port" default="8889" />
<arg name="local_cmd_client_port" default="8890" />
<arg name="local_vid_server_port" default="6038" />
<arg name="namespace" default="tello" />

<group ns="$(arg namespace)">
<node pkg="tello_driver" name="tello" type="tello_driver_node.py" output="screen">
<param name="client_port" value="$(arg client_port)" />
<param name="local_cmd_client_port" value="$(arg local_cmd_client_port)" />
<param name="local_vid_server_port" value="$(arg local_vid_server_port)" />
<param name="tello_ip" value="$(arg tello_ip)" />
<param name="tello_cmd_port" value="$(arg tello_cmd_port)" />
<param name="tello_cmd_server_port" value="$(arg tello_cmd_server_port)" />
<param name="connect_timeout_sec" value="10.0" />
</node>

<node pkg="image_transport" name="image_compressed" type="republish" args="raw in:=image_raw compressed out:=image_raw" />
</group>
</launch>
</launch>
13 changes: 9 additions & 4 deletions src/tello_driver_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ def notify_cmd_success(cmd, success):

class TelloNode(tello.Tello):
def __init__(self):
self.client_port = int(rospy.get_param('~client_port', 8890))
self.local_cmd_client_port = int(
rospy.get_param('~local_cmd_client_port', 8890))
self.local_vid_server_port = int(
rospy.get_param('~local_vid_server_port', 6038))
self.tello_ip = rospy.get_param('~tello_ip', '192.168.10.1')
self.tello_cmd_port = int(rospy.get_param('~tello_cmd_port', 8889))
self.tello_cmd_server_port = int(
rospy.get_param('~tello_cmd_server_port', 8889))
self.connect_timeout_sec = float(
rospy.get_param('~connect_timeout_sec', 10.0))
self.bridge = CvBridge()
Expand All @@ -65,9 +69,10 @@ def __init__(self):
log = RospyLogger('Tello')
log.set_level(self.LOG_WARN)
super(TelloNode, self).__init__(
client_port=self.client_port,
local_cmd_client_port=self.local_cmd_client_port,
local_vid_server_port=self.local_vid_server_port,
tello_ip=self.tello_ip,
tello_cmd_port=self.tello_cmd_port,
tello_cmd_server_port=self.tello_cmd_server_port,
log=log)
rospy.loginfo('Connecting to drone @ %s:%d' % self.tello_addr)
self.connect()
Expand Down
4 changes: 3 additions & 1 deletion wifi_docker_proxy/config.ini.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ image_name=wifiproxy
; may be updated by go.py
container_name=proxy1
wifi_dev=wlan1
drone_ap=TELLO-C62D82
drone_ap=TELLO-C62D82
local_cmd_client_port=8890
local_vid_server_port=6038
24 changes: 24 additions & 0 deletions wifi_docker_proxy/get_phyid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python

# Script to parse output from `iw dev`, and returns the physical device
# listed above an user-specified wifi network device

import os
import sys

if len(sys.argv) < 2:
sys.stderr.write('Usage: %s <WIFI_DEV>\n' % sys.argv[0])
sys.exit(1)

wifi_dev = sys.argv[1]
phyid = None
for line in os.popen('iw dev').readlines():
if len(line) <= 0:
continue
elif line.find('phy#') == 0:
phyid = 'phy'+line.strip()[4:]
elif line.find(wifi_dev) > 0:
print(phyid)
sys.exit(0)
print('')
sys.exit(1)
15 changes: 14 additions & 1 deletion wifi_docker_proxy/go.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,23 @@ def parse_args():
help='Drone\'s access point name '
'[retrieved from config.ini]',
type=str, default='')
parser.add_argument('--local_cmd_client_port', dest='LOCAL_CMD_CLIENT_PORT',
help='Local port bound to Drone\'s command server '
'[retrieved from config.ini]',
type=str, default='')
parser.add_argument('--local_vid_server_port', dest='LOCAL_VID_SERVER_PORT',
help='Local port for video stream server from Drone '
'[retrieved from config.ini]',
type=str, default='')
args = parser.parse_args()
return args, parser


def merge_args(cfg, args):
if 'Session' not in cfg:
cfg['Session'] = {}
for key in ['CONTAINER_NAME', 'WIFI_DEV', 'DRONE_AP']:
for key in ('CONTAINER_NAME', 'WIFI_DEV', 'DRONE_AP',
'LOCAL_CMD_CLIENT_PORT', 'LOCAL_VID_SERVER_PORT'):
if not hasattr(args, key):
continue
val = getattr(args, key)
Expand Down Expand Up @@ -114,11 +123,15 @@ def dispatcher():
container_name = cfg['Session']['CONTAINER_NAME']
wifi_dev = cfg['Session']['WIFI_DEV']
drone_ap = cfg['Session']['DRONE_AP']
local_cmd_client_port = cfg['Session']['LOCAL_CMD_CLIENT_PORT']
local_vid_server_port = cfg['Session']['LOCAL_VID_SERVER_PORT']

cmds.append(['docker', 'run',
'-d', '--rm', '--privileged',
'--env', 'DRONE_AP='+drone_ap,
'--env', 'WIFI_DEV='+wifi_dev,
'--env', 'LOCAL_CMD_CLIENT_PORT='+local_cmd_client_port,
'--env', 'LOCAL_VID_SERVER_PORT='+local_vid_server_port,
'--name', container_name,
image_name])
cmds.append(['./setup_network.sh', container_name, wifi_dev])
Expand Down
14 changes: 10 additions & 4 deletions wifi_docker_proxy/payload/connect_drone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,25 @@ pkill dhclient

# Verify if device is connected to wifi (a.k.a. is allocated an IP)
WIFI_IP=$(ip a | grep $WIFI_DEV | pcregrep -o1 'inet ([0-9]+.[0-9]+.[0-9]+.[0-9]+)')
if [ -z '$WIFI_IP' ]
if [ -z "$WIFI_IP" ]
then
# Warn user
echo '! proxy container did not get IP from drone wifi (is drone turned on?)'
iwconfig $WIFI_DEV
ifconfig $WIFI_DEV
exit 1
else
DOCKER_VETH_HOST_IP='172.17.0.1' # Hardcoded by Docker
DRONE_IP='192.168.10.1' # Hardcoded by drone
DRONE_CMD_SERVER_PORT=8889 # Hardcoded by drone's UDP protocol
PROXY_CMD_CLIENT_PORT=$LOCAL_CMD_CLIENT_PORT
PROXY_VID_CLIENT_PORT=$((LOCAL_VID_SERVER_PORT+1))

# Setup socat UDP port forwarding
# CMD SERVER: drone (192.168.10.1:8889) <-> docker (192.168.10.2:8890 / 172.17.0.XYZ:8889) <-> host ( 172.17.0.1:port)
# VIDEO SERVER: host ( 172.17.0.1:6038) <-> docker (172.17.0.XYZ:6039 / 192.168.10.2:6038) <-> drone (192.168.10.1:port)
nohup /usr/bin/socat UDP4-LISTEN:8889,fork UDP4:192.168.10.1:8889,bind=:8890 &>/dev/null &
nohup /usr/bin/socat UDP4-LISTEN:6038,fork UDP4:172.17.0.1:6038,bind=:6039 &>/dev/null &
nohup /usr/bin/socat UDP4-LISTEN:$DRONE_CMD_SERVER_PORT,fork UDP4:$DRONE_IP:$DRONE_CMD_SERVER_PORT,bind=:$PROXY_CMD_CLIENT_PORT &>/dev/null &
nohup /usr/bin/socat UDP4-LISTEN:$LOCAL_VID_SERVER_PORT,fork UDP4:$DOCKER_VETH_HOST_IP:$LOCAL_VID_SERVER_PORT,bind=:$PROXY_VID_CLIENT_PORT &>/dev/null &

# Notify user
echo '- proxy container connected to drone wifi via '$WIFI_IP
Expand All @@ -35,4 +41,4 @@ else
echo ''
echo $CONTAINER_IP
exit 0
fi
fi
13 changes: 11 additions & 2 deletions wifi_docker_proxy/setup_network.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@ for path in /var/run/netns/*; do if [ -L "$path" ] && ! [ -e "$path" ]; then sud
sudo ln -s /proc/$PID/ns/net /var/run/netns/$PID

# Assign physical device for wifi dongle to container's network namespace
PHYID=phy$(iw dev | grep -B 1 $WIFI_DEV | pcregrep -o1 'phy\#([0-9]+)')
sudo iw phy $PHYID set netns $PID
#PHYID=phy$(iw dev | grep -B 1 $WIFI_DEV | pcregrep -o1 'phy\#([0-9]+)') # doesn't work in all cases
PHYID=$(./get_phyid.py $WIFI_DEV)
if [ -z "$PHYID" ]
then
echo "! could not find physical device for $WIFI_DEV"
iw dev
exit 1
else
sudo iw phy $PHYID set netns $PID
echo "- SUCCESS! Wifi device $WIFI_DEV ($PHYID) now accessible by container $CONTAINER_NAME"
fi

# From now on, assuming the container is '--privileged', it will be able to interact with the wifi dongle

0 comments on commit aba20f4

Please sign in to comment.