Add files used for project
This commit is contained in:
parent
110d3d9684
commit
6046e76a85
24
.devcontainer/devcontainer.json
Executable file
24
.devcontainer/devcontainer.json
Executable file
@ -0,0 +1,24 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/python
|
||||
{
|
||||
"name": "Python 3",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/python:0-3.11",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-python.python"
|
||||
]
|
||||
}
|
||||
},
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "pip3 install --user -r requirements.txt",
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
BIN
additional_files/Benjamin Plaque.png
Executable file
BIN
additional_files/Benjamin Plaque.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
3079
additional_files/ChatGPT Transcript.txt
Executable file
3079
additional_files/ChatGPT Transcript.txt
Executable file
File diff suppressed because it is too large
Load Diff
BIN
additional_files/Final_Red_Parts.stl
Executable file
BIN
additional_files/Final_Red_Parts.stl
Executable file
Binary file not shown.
BIN
additional_files/Final_White_Parts.stl
Executable file
BIN
additional_files/Final_White_Parts.stl
Executable file
Binary file not shown.
BIN
additional_files/Plaque.3mf
Executable file
BIN
additional_files/Plaque.3mf
Executable file
Binary file not shown.
BIN
additional_files/Plaque.stl
Executable file
BIN
additional_files/Plaque.stl
Executable file
Binary file not shown.
23971
additional_files/stl.obj
Executable file
23971
additional_files/stl.obj
Executable file
File diff suppressed because it is too large
Load Diff
BIN
additional_files/wheel and connector.stl
Executable file
BIN
additional_files/wheel and connector.stl
Executable file
Binary file not shown.
BIN
additional_files/wheel only.3mf
Executable file
BIN
additional_files/wheel only.3mf
Executable file
Binary file not shown.
BIN
additional_files/wheel only.stl
Executable file
BIN
additional_files/wheel only.stl
Executable file
Binary file not shown.
1
requirements.txt
Executable file
1
requirements.txt
Executable file
@ -0,0 +1 @@
|
||||
tkinter
|
191
src/piston.py
Executable file
191
src/piston.py
Executable file
@ -0,0 +1,191 @@
|
||||
import tkinter as tk
|
||||
import os
|
||||
import math
|
||||
import time
|
||||
|
||||
|
||||
is_pi = True
|
||||
try:
|
||||
import RPi.GPIO as GPIO
|
||||
print("Detected Raspberry Pi!")
|
||||
except RuntimeError:
|
||||
print("Detected not a Raspberry Pi!")
|
||||
is_pi = False
|
||||
|
||||
|
||||
def perform_movement_operation():
|
||||
if not is_pi:
|
||||
return
|
||||
in1 = 21
|
||||
in2 = 20
|
||||
in3 = 16
|
||||
in4 = 12
|
||||
GPIO.cleanup()
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(in1, GPIO.OUT)
|
||||
GPIO.setup(in2, GPIO.OUT)
|
||||
GPIO.setup(in3, GPIO.OUT)
|
||||
GPIO.setup(in4, GPIO.OUT)
|
||||
GPIO.output(in1, GPIO.LOW)
|
||||
GPIO.output(in2, GPIO.LOW)
|
||||
GPIO.output(in3, GPIO.LOW)
|
||||
GPIO.output(in4, GPIO.LOW)
|
||||
# Stepper motor parameters
|
||||
step_sleep = 0.001
|
||||
step_count = 2048 # 5.625*(1/64) per step, 4096 steps is 360°
|
||||
direction = True # True for clockwise, False for counter-clockwise
|
||||
# defining stepper motor sequence (found in documentation http://www.4tronix.co.uk/arduino/Stepper-Motors.php)
|
||||
step_sequence = [[1, 0, 0, 1],
|
||||
[1, 0, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 1, 1, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1]]
|
||||
motor_pins = [in1, in2, in3, in4]
|
||||
motor_step_counter = 0
|
||||
|
||||
try:
|
||||
i = 0
|
||||
for i in range(step_count):
|
||||
for pin in range(0, len(motor_pins)):
|
||||
GPIO.output(motor_pins[pin],
|
||||
step_sequence[motor_step_counter][pin])
|
||||
if direction == True:
|
||||
motor_step_counter = (motor_step_counter - 1) % 8
|
||||
elif direction == False:
|
||||
motor_step_counter = (motor_step_counter + 1) % 8
|
||||
time.sleep(step_sleep)
|
||||
|
||||
except Exception as ex:
|
||||
print (ex)
|
||||
exit(1)
|
||||
time.sleep(0)
|
||||
|
||||
class PistonApp:
|
||||
def __init__(self):
|
||||
self.root = tk.Tk()
|
||||
self.canvas = tk.Canvas(self.root, width=480, height=370)
|
||||
self.canvas.pack()
|
||||
self.piston = self.canvas.create_rectangle(
|
||||
75, 50, 400, 150, fill='gray')
|
||||
self.crankshaft = self.canvas.create_oval(
|
||||
190, 230, 290, 330, fill='black')
|
||||
self.connecting_rod = self.canvas.create_line(0, 0, 0, 0, fill='black')
|
||||
self.stroke_length = 50
|
||||
self.stroke = 1
|
||||
self.theta = 0
|
||||
self.manual_mode = False
|
||||
self.delay = 400
|
||||
self.stroke_label=tk.Label(self.root, font=("Arial", 50),text="")
|
||||
self.stroke_label.pack()
|
||||
self.last_stroke='up'
|
||||
self.manual_mode_var = tk.BooleanVar()
|
||||
self.manual_mode_var.set(False)
|
||||
self.manual_mode_checkbox = tk.Checkbutton(
|
||||
self.root, text="Minecraft Mode", font=("Arial", 30), variable=self.manual_mode_var, command=self.toggle_manual_mode)
|
||||
self.manual_mode_checkbox.pack()
|
||||
|
||||
self.next_button = tk.Button(
|
||||
self.root, text="Next", height=4, width=14, command=self.next_operation, font=("Arial", 20), state=tk.DISABLED)
|
||||
self.next_button.pack()
|
||||
|
||||
self.root.after(1000, self.synchronize_engine)
|
||||
|
||||
|
||||
|
||||
def toggle_manual_mode(self):
|
||||
self.manual_mode = self.manual_mode_var.get()
|
||||
if self.manual_mode:
|
||||
self.next_button.config(state=tk.NORMAL)
|
||||
else:
|
||||
self.next_button.config(state=tk.DISABLED)
|
||||
self.root.after(0, self.synchronize_engine)
|
||||
|
||||
def next_operation(self):
|
||||
if self.manual_mode:
|
||||
if self.last_stroke == 'up':
|
||||
self.animate_downstroke()
|
||||
self.last_stroke = 'down'
|
||||
else:
|
||||
self.animate_upstroke()
|
||||
self.last_stroke = 'up'
|
||||
|
||||
def synchronize_engine(self):
|
||||
if not self.manual_mode:
|
||||
if self.last_stroke=='up':
|
||||
self.animate_downstroke()
|
||||
self.root.after(self.delay, self.animate_upstroke)
|
||||
self.root.after(self.delay * 2, self.synchronize_engine)
|
||||
|
||||
def update_connecting_rod(self):
|
||||
piston_coords = self.canvas.coords(self.piston)
|
||||
px = (piston_coords[0] + piston_coords[2]) / 2
|
||||
py = piston_coords[3]
|
||||
crankshaft_coords = self.canvas.coords(self.crankshaft)
|
||||
cx = (crankshaft_coords[0] + crankshaft_coords[2]) / 2
|
||||
cy = (crankshaft_coords[1] + crankshaft_coords[3]) / 2
|
||||
r = (crankshaft_coords[3] - crankshaft_coords[1]) / 2
|
||||
if self.theta < math.pi / 2:
|
||||
px2 = cx
|
||||
py2 = cy - math.sqrt(r**2 - (cx - px2)**2)
|
||||
else:
|
||||
px2 = cx
|
||||
py2 = cy + math.sqrt(r**2 - (cx - px2)**2)
|
||||
self.canvas.coords(self.connecting_rod, px, py, px2, py2)
|
||||
|
||||
def animate_downstroke(self):
|
||||
self.canvas.move(self.piston, 0, self.stroke_length)
|
||||
if self.stroke == 1:
|
||||
self.canvas.itemconfig(self.piston, fill='blue')
|
||||
self.stroke_label.config(text="intake")
|
||||
elif self.stroke == 3:
|
||||
self.canvas.itemconfig(self.piston, fill='red')
|
||||
self.stroke_label.config(text="power")
|
||||
|
||||
self.update_connecting_rod()
|
||||
self.stroke += 1
|
||||
self.rotate_crankshaft()
|
||||
self.last_stroke = 'down'
|
||||
if self.manual_mode:
|
||||
self.next_button.config(state='normal')
|
||||
self.canvas.update()
|
||||
perform_movement_operation()
|
||||
|
||||
def animate_upstroke(self):
|
||||
self.canvas.update()
|
||||
self.stroke_label.update()
|
||||
self.canvas.move(self.piston, 0, -self.stroke_length)
|
||||
if self.stroke == 2:
|
||||
self.canvas.itemconfig(self.piston, fill='orange')
|
||||
self.stroke_label.config(text="compression")
|
||||
elif self.stroke == 4:
|
||||
self.canvas.itemconfig(self.piston, fill='brown')
|
||||
self.stroke_label.config(text="exhaust")
|
||||
self.update_connecting_rod()
|
||||
if self.stroke == 4:
|
||||
self.stroke = 1
|
||||
else:
|
||||
self.stroke += 1
|
||||
self.rotate_crankshaft()
|
||||
self.last_stroke = 'up'
|
||||
|
||||
if self.manual_mode:
|
||||
self.next_button.config(state='normal')
|
||||
self.canvas.update()
|
||||
perform_movement_operation()
|
||||
self.canvas.update()
|
||||
self.stroke_label.update()
|
||||
|
||||
def rotate_crankshaft(self):
|
||||
self.theta += math.pi / 12 # 30 degrees
|
||||
self.canvas.delete(self.connecting_rod)
|
||||
self.connecting_rod = self.canvas.create_line(0, 0, 0, 0, fill='black')
|
||||
self.update_connecting_rod()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = PistonApp()
|
||||
app.root.mainloop()
|
Loading…
x
Reference in New Issue
Block a user