Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 1 | import gi |
| 2 | gi.require_version('Gtk', '3.0') |
| 3 | from gi.repository import Gtk |
| 4 | import numpy as np |
Ravago Jones | 56941a5 | 2021-07-31 14:42:38 -0700 | [diff] [blame] | 5 | import queue |
| 6 | import threading |
| 7 | import copy |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 8 | from points import Points |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 9 | from libspline import Spline, DistanceSpline, Trajectory |
| 10 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 11 | from matplotlib.backends.backend_gtk3agg import (FigureCanvasGTK3Agg as |
| 12 | FigureCanvas) |
| 13 | from matplotlib.figure import Figure |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 14 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 15 | class Graph(Gtk.Bin): |
| 16 | def __init__(self): |
| 17 | super(Graph, self).__init__() |
| 18 | fig = Figure(figsize=(5, 4), dpi=100) |
| 19 | self.axis = fig.add_subplot(111) |
Ravago Jones | e958479 | 2022-05-28 16:16:46 -0700 | [diff] [blame^] | 20 | self.canvas = FigureCanvas(fig) # a Gtk.DrawingArea |
| 21 | self.canvas.set_vexpand(True) |
| 22 | self.canvas.set_size_request(800, 250) |
| 23 | self.add(self.canvas) |
Ravago Jones | 56941a5 | 2021-07-31 14:42:38 -0700 | [diff] [blame] | 24 | self.queue = queue.Queue(maxsize=1) |
| 25 | |
| 26 | thread = threading.Thread(target=self.worker) |
| 27 | thread.daemon = True |
| 28 | thread.start() |
| 29 | |
| 30 | def schedule_recalculate(self, points): |
| 31 | if not points.getLibsplines() or self.queue.full(): return |
| 32 | new_copy = copy.deepcopy(points) |
| 33 | |
| 34 | # empty the queue |
| 35 | try: |
| 36 | self.queue.get_nowait() |
| 37 | except queue.Empty: |
| 38 | pass # was already empty |
| 39 | |
| 40 | # replace with new request |
| 41 | self.queue.put_nowait(new_copy) |
| 42 | |
| 43 | def worker(self): |
| 44 | while True: |
| 45 | self.recalculate_graph(self.queue.get()) |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 46 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 47 | def recalculate_graph(self, points): |
| 48 | if not points.getLibsplines(): return |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 49 | # set the size of a timestep |
| 50 | dt = 0.00505 |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 51 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 52 | # call C++ wrappers to calculate the trajectory |
| 53 | distanceSpline = DistanceSpline(points.getLibsplines()) |
| 54 | traj = Trajectory(distanceSpline) |
| 55 | points.addConstraintsToTrajectory(traj) |
| 56 | traj.Plan() |
| 57 | XVA = traj.GetPlanXVA(dt) |
Ravago Jones | 56941a5 | 2021-07-31 14:42:38 -0700 | [diff] [blame] | 58 | if XVA is None: return |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 59 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 60 | # extract values to be graphed |
| 61 | total_steps_taken = XVA.shape[1] |
| 62 | total_time = dt * total_steps_taken |
Ravago Jones | 56941a5 | 2021-07-31 14:42:38 -0700 | [diff] [blame] | 63 | time = np.linspace(0, total_time, num=total_steps_taken) |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 64 | position, velocity, acceleration = XVA |
| 65 | left_voltage, right_voltage = zip(*(traj.Voltage(x) for x in position)) |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 66 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 67 | # update graph |
| 68 | self.axis.clear() |
| 69 | self.axis.plot(time, velocity) |
| 70 | self.axis.plot(time, acceleration) |
| 71 | self.axis.plot(time, left_voltage) |
| 72 | self.axis.plot(time, right_voltage) |
| 73 | self.axis.legend( |
| 74 | ["Velocity", "Acceleration", "Left Voltage", "Right Voltage"]) |
| 75 | self.axis.xaxis.set_label_text("Time (sec)") |
John Park | 91e6973 | 2019-03-03 13:12:43 -0800 | [diff] [blame] | 76 | |
Ravago Jones | 6d460fe | 2021-07-03 16:59:55 -0700 | [diff] [blame] | 77 | # renumber the x-axis to include the last point, |
| 78 | # the total time to drive the spline |
| 79 | self.axis.xaxis.set_ticks(np.linspace(0, total_time, num=8)) |
Ravago Jones | 128fb99 | 2021-07-31 13:56:58 -0700 | [diff] [blame] | 80 | |
Ravago Jones | e958479 | 2022-05-28 16:16:46 -0700 | [diff] [blame^] | 81 | # redraw |
| 82 | self.canvas.draw() |