「树莓派」3D打印制作,可全自动连发的诸葛神弩

连弩又称”诸葛弩”,相传为诸葛亮所制,可连续发射弩箭。但由于连弩用箭没有箭羽,使铁箭在远距离飞行时会失去平衡而翻滚,且木制箭杆的制作要求精度高,人工制作难度大,不易大量制造使用。明朝以后,由于火器迅速发展,弩便不再受重视。

「树莓派」3D打印制作,可全自动连发的诸葛神弩

今天我们使用建模软件和3D打印技术制作一把可全自动连发的弩,使用树莓派控制舵机运动,程序代码全部为Python编写,包括一个2个自由度的云台。上弹以及发射动作由两个舵机和棘轮结构完成,可以通过增加橡皮筋的数量来改变射击力量。

STL模型和程序已经开源,可以免费下载:

***/learn/1070.html

弹药为大约10x10x4的小方块,由于3D打印机精度各不相同所以这里不提供这个小方块的模型。

实验所用的代码如下:

#!/usr/bin/python3# File name : crossbow.py# Author : William# Date : 2019/10/09import Adafruit_PCA9685import timeimport socketimport threadingpwm = Adafruit_PCA9685.PCA9685()pwm.set_pwm_freq(50)port_L = 0port_R = 1port_P = 2port_T = 3direction_L = 1direction_R = -1direction_P = -1direction_T = -1servo_middle_L = 290servo_middle_R = 280servo_middle_P = 300servo_middle_T = 300P_position = servo_middle_PT_position = servo_middle_TPT_speed = 1P_command = ''T_command = ''CB_command = ''nocked = 0wiggle_f = 60wiggle_b = 90wiggle_loose = 60steps_delay = 0.15draw_steps = 5time_delay = 0.001def hold(): pwm.set_pwm(port_L, 0, servo_middle_L) pwm.set_pwm(port_R, 0, servo_middle_R)def draw(steps): global nocked for i in range(0, steps): pwm.set_pwm(port_L, 0, servo_middle_L + wiggle_f*direction_L) pwm.set_pwm(port_R, 0, servo_middle_R - wiggle_b*direction_R) time.sleep(steps_delay) pwm.set_pwm(port_L, 0, servo_middle_L - wiggle_b*direction_L) pwm.set_pwm(port_R, 0, servo_middle_R - wiggle_b*direction_R) time.sleep(steps_delay) pwm.set_pwm(port_L, 0, servo_middle_L - wiggle_b*direction_L) pwm.set_pwm(port_R, 0, servo_middle_R + wiggle_f*direction_R) time.sleep(steps_delay) pwm.set_pwm(port_L, 0, servo_middle_L - wiggle_b*direction_L) pwm.set_pwm(port_R, 0, servo_middle_R - wiggle_b*direction_R) time.sleep(steps_delay) hold() nocked = 1 time.sleep(steps_delay)def loose(): global nocked if nocked: pwm.set_pwm(port_L, 0, servo_middle_L + wiggle_loose*direction_L) pwm.set_pwm(port_R, 0, servo_middle_R + wiggle_loose*direction_R) time.sleep(steps_delay) nocked = 0 else: draw(draw_steps) pwm.set_pwm(port_L, 0, servo_middle_L + wiggle_loose*direction_L) pwm.set_pwm(port_R, 0, servo_middle_R + wiggle_loose*direction_R) time.sleep(steps_delay) nocked = 0def up(speed_input): global T_position T_position+=speed_input*direction_T pwm.set_pwm(port_T, 0, T_position)def down(speed_input): global T_position T_position-=speed_input*direction_T pwm.set_pwm(port_T, 0, T_position)def left(speed_input): global P_position P_position-=speed_input*direction_P pwm.set_pwm(port_P, 0, P_position)def right(speed_input): global P_position P_position+=speed_input*direction_P pwm.set_pwm(port_P, 0, P_position)class PT_ctrl(threading.Thread): def __init__(self, *args, **kwargs): super(PT_ctrl, self).__init__(*args, **kwargs) self.__flag = threading.Event() self.__flag.set() self.__running = threading.Event() self.__running.set() def run(self): while self.__running.isSet(): self.__flag.wait() if T_command == 'up': up(PT_speed) elif T_command == 'down': down(PT_speed) if P_command == 'left': left(PT_speed) print('11') elif P_command == 'right': right(PT_speed) if P_command == 'P_no' and T_command =='T_no': self.pause() time.sleep(time_delay) def pause(self): self.__flag.clear() def resume(self): self.__flag.set() def stop(self): self.__flag.set() self.__running.clear()class CB_ctrl(threading.Thread): def __init__(self, *args, **kwargs): super(CB_ctrl, self).__init__(*args, **kwargs) self.__flag = threading.Event() self.__flag.set() self.__running = threading.Event() self.__running.set() def run(self): global goal_pos, servo_command, init_get, if_continue, walk_step while self.__running.isSet(): self.__flag.wait() if CB_command == 'draw': draw(draw_steps) self.pause() elif CB_command == 'loose': loose() self.pause() time.sleep(time_delay) def pause(self): self.__flag.clear() def resume(self): self.__flag.set() def stop(self): self.__flag.set() self.__running.clear()PT = PT_ctrl()PT.start()PT.pause()CB = CB_ctrl()CB.start()CB.pause()if __name__ == '__main__': HOST = '' PORT = 10223 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpSerSock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) tcpSerSock.bind(ADDR) tcpSerSock.listen(5) print('waiting for connection...') tcpCliSock, addr = tcpSerSock.accept() print('...connected from :', addr) while True: data = '' data = str(tcpCliSock.recv(BUFSIZ).decode()) if not data: continue elif 'draw' == data: CB_command = data CB.resume() elif 'loose' == data: CB_command = data CB.resume() elif 'P_no' in data: P_command = data elif 'T_no' in data: T_command = data elif 'left' == data: P_command = data PT.resume() elif 'right' == data: P_command = data PT.resume() elif 'up' in data: T_command = data PT.resume() elif 'down' in data: T_command = data PT.resume() print(data)

本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:dandanxi6@qq.com

(0)
上一篇 2023年5月2日 上午8:39
下一篇 2023年5月2日 上午9:28

相关推荐