Spline UI run graph calculations on thread
Much smoother when the gtk event loop isn't as clogged
Signed-off-by: Ravago Jones <ravagojones@gmail.com>
Change-Id: Ied4b0a8bd80957a1e3ae09ccf977a5f4ac3373eb
diff --git a/frc971/control_loops/python/graph.py b/frc971/control_loops/python/graph.py
index 456edd1..c974d68 100644
--- a/frc971/control_loops/python/graph.py
+++ b/frc971/control_loops/python/graph.py
@@ -2,6 +2,9 @@
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import numpy as np
+import queue
+import threading
+import copy
from points import Points
from libspline import Spline, DistanceSpline, Trajectory
@@ -9,7 +12,6 @@
FigureCanvas)
from matplotlib.figure import Figure
-
class Graph(Gtk.Bin):
def __init__(self):
super(Graph, self).__init__()
@@ -19,10 +21,31 @@
canvas.set_vexpand(True)
canvas.set_size_request(800, 250)
self.add(canvas)
+ self.queue = queue.Queue(maxsize=1)
+
+ thread = threading.Thread(target=self.worker)
+ thread.daemon = True
+ thread.start()
+
+ def schedule_recalculate(self, points):
+ if not points.getLibsplines() or self.queue.full(): return
+ new_copy = copy.deepcopy(points)
+
+ # empty the queue
+ try:
+ self.queue.get_nowait()
+ except queue.Empty:
+ pass # was already empty
+
+ # replace with new request
+ self.queue.put_nowait(new_copy)
+
+ def worker(self):
+ while True:
+ self.recalculate_graph(self.queue.get())
def recalculate_graph(self, points):
if not points.getLibsplines(): return
-
# set the size of a timestep
dt = 0.00505
@@ -32,11 +55,12 @@
points.addConstraintsToTrajectory(traj)
traj.Plan()
XVA = traj.GetPlanXVA(dt)
+ if XVA is None: return
# extract values to be graphed
total_steps_taken = XVA.shape[1]
total_time = dt * total_steps_taken
- time = np.arange(total_time, step=dt)
+ time = np.linspace(0, total_time, num=total_steps_taken)
position, velocity, acceleration = XVA
left_voltage, right_voltage = zip(*(traj.Voltage(x) for x in position))
@@ -54,4 +78,5 @@
# the total time to drive the spline
self.axis.xaxis.set_ticks(np.linspace(0, total_time, num=8))
+ # ask to be redrawn
self.queue_draw()
diff --git a/frc971/control_loops/python/path_edit.py b/frc971/control_loops/python/path_edit.py
index c639379..50400b9 100755
--- a/frc971/control_loops/python/path_edit.py
+++ b/frc971/control_loops/python/path_edit.py
@@ -259,7 +259,7 @@
pxToM(self.mousey), difs)
self.points.update_lib_spline()
- self.graph.recalculate_graph(self.points)
+ self.graph.schedule_recalculate(self.points)
self.queue_draw()
def export_json(self, file_name):
@@ -374,7 +374,7 @@
self.points.splineExtrapolate(self.spline_edit)
self.points.update_lib_spline()
- self.graph.recalculate_graph(self.points)
+ self.graph.schedule_recalculate(self.points)
self.index_of_edit = -1
self.spline_edit = -1
diff --git a/frc971/control_loops/python/points.py b/frc971/control_loops/python/points.py
index d874306..5fc4c4a 100644
--- a/frc971/control_loops/python/points.py
+++ b/frc971/control_loops/python/points.py
@@ -1,7 +1,7 @@
from constants import *
import numpy as np
from libspline import Spline, DistanceSpline, Trajectory
-
+import copy
class Points():
def __init__(self):
@@ -21,6 +21,14 @@
}
]
+ def __deepcopy__(self, memo):
+ new_copy = Points()
+ new_copy.points = copy.deepcopy(self.points, memo)
+ new_copy.splines = copy.deepcopy(self.splines, memo)
+ new_copy.constraints = copy.deepcopy(self.constraints, memo)
+ new_copy.update_lib_spline()
+ return new_copy
+
def getPoints(self):
return self.points