Skip to content

Commit 8ae580e

Browse files
authored
feat: RoboticArm CSV import/export (#256)
1 parent b97ee9a commit 8ae580e

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

pslab/external/motor.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
import time
1111
from typing import List
1212
from typing import Union
13+
import csv
14+
import os
1315

1416
from pslab.instrument.waveform_generator import PWMGenerator
17+
from datetime import datetime
1518

1619
MICROSECONDS = 1e6
1720

@@ -96,7 +99,7 @@ def run_schedule(self, timeline: List[List[int]], time_step: float = 1.0) -> Non
9699
with angles corresponding to each servo.
97100
98101
time_step : float, optional
99-
Delay in seconds between each timestep. Default is 1.0.
102+
Delay in seconds between each timestep. Default is 1.0.
100103
"""
101104
if len(timeline[0]) != len(self.servos):
102105
raise ValueError("Each timestep must specify an angle for every servo")
@@ -107,5 +110,60 @@ def run_schedule(self, timeline: List[List[int]], time_step: float = 1.0) -> Non
107110

108111
for tl in timeline:
109112
for i, s in enumerate(self.servos):
110-
s.angle = tl[i]
113+
if tl[i] is not None:
114+
s.angle = tl[i]
111115
time.sleep(time_step)
116+
117+
def import_timeline_from_csv(self, filepath: str) -> List[List[int]]:
118+
"""Import timeline from a CSV file.
119+
120+
Parameters
121+
----------
122+
filepath : str
123+
Absolute or relative path to the CSV file to be read.
124+
125+
Returns
126+
-------
127+
List[List[int]]
128+
A timeline consisting of servo angle values per timestep.
129+
"""
130+
timeline = []
131+
132+
with open(filepath, mode="r", newline="") as csvfile:
133+
reader = csv.DictReader(csvfile)
134+
for row in reader:
135+
angles = []
136+
for key in ["Servo1", "Servo2", "Servo3", "Servo4"]:
137+
value = row[key]
138+
if value == "null":
139+
angles.append(None)
140+
else:
141+
angles.append(int(value))
142+
timeline.append(angles)
143+
144+
return timeline
145+
146+
def export_timeline_to_csv(
147+
self, timeline: List[List[Union[int, None]]], folderpath: str
148+
) -> None:
149+
"""Export timeline to a CSV file.
150+
151+
Parameters
152+
----------
153+
timeline : List[List[Union[int, None]]]
154+
A list of timesteps where each sublist contains servo angles.
155+
156+
folderpath : str
157+
Directory path where the CSV file will be saved. The filename
158+
will include a timestamp to ensure uniqueness.
159+
"""
160+
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
161+
filename = f"Robotic_Arm{timestamp}.csv"
162+
filepath = os.path.join(folderpath, filename)
163+
164+
with open(filepath, mode="w", newline="") as csvfile:
165+
writer = csv.writer(csvfile)
166+
writer.writerow(["Timestep", "Servo1", "Servo2", "Servo3", "Servo4"])
167+
for i, row in enumerate(timeline):
168+
pos = ["null" if val is None else val for val in row]
169+
writer.writerow([i] + pos)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy