PyNetworkTables custom dashboard help

We are trying and not not having luck with a custom dashboard. The attached code renders a field and then renders 2 locations on top of the field. The x,y,yaw of the robot, and the x,y,yaw of the path the robot is trying to follow.

Also attached is a script that generates dummy data and publishes it over network tables for testing. When using this script it works as expected.

When changing the IP address that the liveObserverPlotter connects to to be the robot (10.24.81.2) it doesn’t work. When debugging and stepping through the code NetworkTables appears to be empty as if it didn’t connect.

To help further debug the problem we took a Wireshark trace. It is clear that the connection is being established because we see all the keys being sent from the robot to the laptop running our custom dashboard.

Given this works when the network tables server is hosted locally on the same laptop we are at a loss as to why this isn’t working.

We are using network tables 2018.1 via pip install pynetworktables

Any help would be greatly appreciated.

live_observer_plotter.zip (3.58 KB)


live_observer_plotter.zip (3.58 KB)

NetworkTables doesn’t connect instantaneously, so the methodology you’re using to do this won’t work (and shouldn’t have worked locally).

To wait for the connection, add the following after your initialize call:



import threading

cond = threading.Condition()
notified = [False]

def connectionListener(connected, info):
    print(info, '; Connected=%s' % connected)
    with cond:
        notified[0] = True
        cond.notify()

NetworkTables.addConnectionListener(connectionListener, immediateNotify=True)

with cond:
    print("Waiting")
    if not notified[0]:
        cond.wait()
    
print("Wait finished")


Also added to the documentation (once it the doc build finishes):

http://robotpy.readthedocs.io/en/latest/guide/nt.html#client-initialization-driver-station-coprocessor

We understand that the connection takes time. updatePoint is called repeatedly by animation.FuncAnimation. We expected for the connection to not yet have been established for the first few calls but assumed that once the connection was established that the get number calls would start working. We assumed this is why it works with the local ntServer.py script running. Given that updatePoint is called periodically would you still expect us to be having problems?

We will give your suggestion a try tomorrow or Friday.

Thanks!!!

Sorry, I missed the animation bit… yes, I would expect that to work then, assuming the connection is successfully made. I would recommend enabling debug logging then to see if the connection is successful:


import logging
logging.basicConfig(level=logging.DEBUG)

No worries. We will enable logging too and see if that reveals anything.

Thanks again for the help!!

I’m a beginner when it comes to threads. When does cond.notify() run? When the robot is connected? When is the info and status outputted from that same function?

The connectionListener function is called after NetworkTables connects to a server.

Actually, the original code I published had a race condition in it. I edited it with a fix.

Why, in your new code, is the variable “notified” a list? Would it not be easier to just assign it to False, not [False] and refer to the item by index?

I’m dumb. Forgot about scope!

Is this code necessary if the client is only attempting to put, not get, numbers? Will exceptions be raised?

The code won’t help you if you try to put variables, it’s only useful for momentary get. To put variables, you would need to use this AND add a 1-second sleep at the end of your code.

The reality is that networktables isn’t designed to be used with fire and forget scripts, but rather it’s designed to be used with a continuously running thing.

Okay…we enabled logging. We are seeing the following errors.

INFO:nt:NetworkTables initialized in client mode
DEBUG:nt.th:Started thread nt-dispatch-thread-0
DEBUG:nt.th:Started thread nt-client-thread-0
INFO:matplotlib.backends._backend_tk:Could not load matplotlib icon: bad option "foobar": must be aspect, attributes, client, colormapwindows, command, deiconify, focusmodel, forget, frame, geometry, grid, group, iconbitmap, iconify, iconmask, iconname, iconphoto, iconposition, iconwindow, manage, maxsize, minsize, overrideredirect, positionfrom, protocol, resizable, sizefrom, stackorder, state, title, transient, or withdraw
DEBUG:nt:client connected
DEBUG:nt.th:Started thread nt-net-write-0
DEBUG:nt.th:Started thread nt-net-read-0
ERROR:nt:Unhandled exception during handshake
Traceback (most recent call last):
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/network_connection.py", line 248, in _readThreadMain
    handshake_success = self.m_handshake(self, _getMessage, self._sendMessages)
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/dispatcher.py", line 571, in _clientHandshake
    msg = get_msg()
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/network_connection.py", line 236, in _getMessage
    return Message.read(self.m_stream, decoder, self.m_get_entry_type)
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/message.py", line 123, in read
    value = codec.read_value(value_type, rstream)
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/wire.py", line 114, in read_value
    return Value.makeString(self.read_string(rstream))
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/wire.py", line 199, in read_string_v3
    return rstream.read(slen).decode('utf-8')
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xd8 in position 0: invalid continuation byte
INFO:nt:DISCONNECTED 10.24.81.2 port 1735 (Robot)
DEBUG:matplotlib.font_manager:findfont: Matching :family=sans-serif:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0 to DejaVu Sans (u'/Users/kyle/Documents/talon_controller/venv/lib/python2.7/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf') with score of 0.050000
DEBUG:nt.th:Thread nt-net-read-0 exited
DEBUG:nt.th:Thread nt-net-write-0 exited
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
DEBUG:nt:client connected
DEBUG:nt:NetworkConnection stopping (<NetworkConnection 0x113dd41d0 ConnectionInfo(remote_id=u'Robot', remote_ip='10.24.81.2', remote_port=1735, last_update=0, protocol_version=768)>)
DEBUG:nt.th:Started thread nt-net-write-1
DEBUG:nt.th:Started thread nt-net-read-1
ERROR:nt:Unhandled exception during handshake
Traceback (most recent call last):
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/network_connection.py", line 248, in _readThreadMain
    handshake_success = self.m_handshake(self, _getMessage, self._sendMessages)
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/dispatcher.py", line 571, in _clientHandshake
    msg = get_msg()
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/network_connection.py", line 236, in _getMessage
    return Message.read(self.m_stream, decoder, self.m_get_entry_type)
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/message.py", line 123, in read
    value = codec.read_value(value_type, rstream)
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/wire.py", line 114, in read_value
    return Value.makeString(self.read_string(rstream))
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/site-packages/ntcore/wire.py", line 199, in read_string_v3
    return rstream.read(slen).decode('utf-8')
  File "/Users/kyle/src/frc-2018/venv/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc0 in position 0: invalid start byte
INFO:nt:DISCONNECTED 10.24.81.2 port 1735 (Robot)
DEBUG:nt.th:Thread nt-net-read-1 exited
DEBUG:nt.th:Thread nt-net-write-1 exited

Awesome! This is the a similar bug to that which was reported at https://github.com/robotpy/pynetworktables/issues/61#issuecomment-376410216 … I assume it happens every time?

If you can check out the handshake-2018 branch, install it, run it against your robot, if you get that error then there should be a file called ‘file.bin’ in the directory you launched your script from. Send me that file and I can probably push a fix for you relatively quickly.

Alternatively if you have that pcap from Wireshark, that would be useful too.

Yes

We will give this a try tonight.

We can take another Wireshark trace too. Wireshark locked up before I could save the trace last time.

This is addressed in pynetworktables 2018.1.1. See the github issue referenced above for more information.