Skip to content

Commit

Permalink
Fixed #11 by changing how PlotWindow methods are overridden.
Browse files Browse the repository at this point in the history
Added documentation for ARCOS SAY command.
The send_command method of the ARCOS Client now accepts bytes objects
as well as strings.
  • Loading branch information
aarant committed Oct 24, 2017
1 parent 6685dc5 commit afe75a3
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 15 deletions.
Binary file added dist/Soar-1.3.5.tar.gz
Binary file not shown.
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def __getattr__(cls, name):
# built documents.
#
# The short X.Y version.
version = '1.3.4'
version = '1.3.5'
# The full version, including alpha/beta/rc tags.
release = '1.3.4'
release = '1.3.5'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
4 changes: 2 additions & 2 deletions soar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# soar/__init__.py
""" Soar (Snakes on a Robot) v1.3.4
""" Soar (Snakes on a Robot) v1.3.5
An extensible Python framework for both simulating and interacting with robots.
Copyright (C) 2017 Andrew Antonitis. Licensed under the LGPLv3.
"""
__version__ = '1.3.4'
__version__ = '1.3.5'
blerb = 'Soar (Snakes on a Robot) v' + __version__ + ': A Python robotics framework.\n' \
'https://github.com/arantonitis/soar\n\n' \
'Copyright (C) 2017 Andrew Antonitis. Licensed under the LGPLv3.'
Expand Down
14 changes: 9 additions & 5 deletions soar/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def tk_wrap(*args, **kwargs):
return_val = gui.synchronous_future(func, *args, after_idle=True, **kwargs)
if isinstance(return_val, Exception): # If the function returned an exception, raise it
raise return_val
return return_val
return tk_wrap


Expand Down Expand Up @@ -266,12 +267,15 @@ def __init__(self, title='Plotting Window', visible=True):
plots.append(self)

def __getattribute__(self, name):
attr = PlotWindow.__getattribute__(self, name) # Call base class method to avoid infinite recursion
# Wrap class methods so that they run in the Tk mainloop, if not already running in it
if callable(attr) and current_thread() != main_thread():
return tkinter_execute(return_exceptions(attr))
else:
if current_thread() != main_thread(): # If not on the main thread
# Force accessing the attribute to run on the main thread
attr = tkinter_execute(return_exceptions(PlotWindow.__getattribute__))(self, name)
# If the attribute is callable, wrap it so that it runs on the main thread
if callable(attr):
return tkinter_execute(return_exceptions(attr))
return attr
else:
return PlotWindow.__getattribute__(self, name)
else:
def __init__(self, title='Plotting Window', visible=True):
# Ensure the window is not visible, and add the plot to the global list
Expand Down
7 changes: 5 additions & 2 deletions soar/gui/plot_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
Unlike use of the :func:`soar.hooks.tkinter_hook`, use of this module will not force brain methods to run on the
main thread alongside Soar's GUI event loop.
`PlotWindow` is wrapped by the client if it is imported by a Soar brain. This wrapper ensures that the proper mode
(GUI or headless) is enforced, despite what the brain might pass to the constructor.
However, methods of `PlotWindow` *will* run on the main thread, regardless of what thread the other brain methods
run in.
`PlotWindow` is wrapped by the client to ensure that the proper mode (GUI or headless) is enforced regardless
of the arguments passed to the constructor by the brain methods.
The client will also ensure that, if logging is occurring, any `PlotWindow` objects will have their image data
included in the log whenever the controller is shut down.
Expand Down
10 changes: 6 additions & 4 deletions soar/robot/arcos.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@
DHEAD = 13 #: Turn at `SETRV` speed relative to current heading; (+) counterclockwise or (-) clockwise degrees.
SAY = 15
""" Play up to 20 duration, tone sound pairs through User Control panel piezo speaker.
The argument is a string consisting of duration, tone pair bytes. Duration is in 20 millisecond increments.
A value of 0 means silence. The values 1-127 are the corresponding MIDI notes. The remaining values are frequencies
computed as `tone - 127*32` equivalent frequencies from 1-4096, in 32Hz increments.
The argument is a string whose first byte must be the number of (duration, tone) pairs to play, followed by each (duration, tone) pair.
Duration is in 20 millisecond increments.
A value of 0 means silence. The values 1-127 are the corresponding MIDI notes, with 60 being middle C. The remaining values are frequencies
computed as `(tone - 127)*32`, ranging from 1-4096 in 32Hz increments.
"""
CONFIG = 18 #: Request a configuration SIP.
ENCODER = 19 #: Request a single (1), a continuous stream (>1), or stop (0) encoder SIPS.
Expand Down Expand Up @@ -332,6 +333,7 @@ def send_command(self, code, data=None):
Args:
code: The command code. Must be in :data:`soar.robot.arcos.command_types`.
data (optional): The associated command argument, assumed to be of the correct type.
For commands that take a string argument, a `bytes` object may also be used.
Raises:
`Timeout`: If the write timeout of the port was exceeded.
Expand All @@ -347,7 +349,7 @@ def send_command(self, code, data=None):
b = [data & 0xff, (data >> 8) & 0xff]
self.send_packet(code, arg_type, *b)
else: # command_types[code] == str
b = [ord(c) for c in data] # Convert the string to bytes and add a null terminator
b = list(bytes(data))
b.append(0)
arg_type = 0x2b
self.send_packet(code, arg_type, *b)
Expand Down

0 comments on commit afe75a3

Please sign in to comment.