遥控夹爪机器人
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 5 | ||||
| × | 2 | ||||
| × | 8 | ||||
| × | 8 |
应用和在线服务
|
关于这个项目
几个月前,我儿子让我给他做一个遥控机器人。他给了我一份他想要的清单,我们把它缩小到一个可管理的清单:) 这就是我最终为他构建的......
- 拿起 UNO 和 V5 传感器护罩并将它们卡在一起。
- 将连接的 UNO/传感器板放入机器人中心内的夹子支架中。
- 用双面胶带将电机驱动器放在左侧内壁,将蓝牙适配器放在右侧壁上。
对于这个项目,您可以自己制作机箱或选择其他机箱,选择权在您。
第 1 步:所需的软件
您需要下载的东西:
- Arduino IDE
- Python 2.7(完整安装 tkinter)
- pySerial 库
- L9110S 电机控制器库附带 .zip(请参阅此步骤中的文件)
- 下面的机器人代码或附加的 .zip(请参阅此步骤中的文件)
- Python 远程控制应用程序(请参阅此步骤中的文件)
第 2 步:硬件物料清单
您需要的零件如下:
- Runt Rover 半品脱底盘或合适的 4wd 封闭式替代品
- Arduino Uno 或带有 USB 电缆的类似板
- V5 传感器防护罩
- L9110S 电机驱动器(买一对,因为它们便宜)
- MG995 舵机或其他合适的替代品 x2
- HC-05 或 HC-06 蓝牙适配器 x1
- 标准伺服板B x1
- 90 度支架 x1
- 单支架 x2
- 轻量级伺服轮毂(Futaba 525125)x1
- 标准夹爪套件 A x1
- 母对母跳线
- 5 节可充电 AA 电池 (NiMH) 和充电器
- 双面胶带和小拉链
- “AA”5 槽电池组(如果您选择 AA 可充电选项)
- 6v NiMH 或 7.4v 锂离子电池组和充电器
- 1.250" 6-32 螺丝 x2
- .750" 8-32 尼龙垫片 x2
- .500" 6-32 螺钉,带螺母 x8
- .3125" 6-32 螺丝 x8
您可以直接从 eBay 或其他供应商(如 Sparkfun、Adafruit 和 ServoCity)采购许多零件。
购买、收集和下载所有内容后,您就可以开始构建了。
第 3 步:组装 - 底盘
首先按照机箱或视频随附的说明组装机箱。完成后,你应该有类似图像的东西。当您将固定控制器的板放在机器人上时,请确保将其放在中间的孔中。这将在机器人的前部和后部留出空间。
注意:在继续之前,请卸下所有 4 个轮子,以免在安装其他机器人组件的同时损坏电机。
第 4 步:组装夹具
按照本视频中提供的说明组装夹具。完成后你应该有类似图像的东西。
第 5 步:安装夹持器 - 第 1 步
此步骤使用 90 度支架、轻型伺服轮毂和四 (4) 个 .3125" 螺钉:
拿起伺服轮毂并将其放在支架的一侧,然后用 .2125" 螺钉将它们固定在一起,如图所示,然后将其放在一边 将螺母放在两个较短的螺钉上并拧紧 现在将两个单支架,1.250 “螺钉和两个带螺母的 .500" 螺钉、2 个尼龙垫片和伺服板 B。取一个支架并将其放入半品脱机器人的内部,然后将 2 个 1.259" 螺钉拧到左侧孔上(从内部)和右侧的 2 个 .500" 螺钉。如图所示,所有螺钉头都将位于机器人内部。现在将第二个单个支架放在机器人外部的螺钉上。接下来取尼龙垫片并将它们放在伸出的较长 (1.250") 上,然后将伺服板拧到长螺钉上 如果使用普通螺钉,则使用大小合适的六角扳手或螺丝刀拧紧连接到伺服板的螺钉。
根据需要使用图片作为参考。
图> 图> 图> 图>
第 6 步:安装夹持器 - 第 2 步
- 接下来将剩余的舵机放入舵机支架中,脊椎朝上。用 4 颗 .3125" 螺钉将其固定。
- 接下来取上带有伺服轮毂的 90 度支架,并使用 4 个 0.500" 螺钉将夹具安装到它上面,使用 8-32 螺母中的 2 个作为支架和夹具之间的垫片,如图所示。用另一个螺母固定在夹具顶部(如果您将螺钉旋转到另一个方向,则在支架下方)
- 现在拿起夹具组件并将其放置在伺服器上,并使用伺服螺钉(来自您的伺服器包)将其固定到位,牢固地固定它。
完成后,将两根伺服线穿过扁平支架孔到达机器人内部。
请参阅图片以获取更多详细信息和参考。
图> 图> 图> 图>
第 7 步:安装电子设备
- 拿起 UNO 和 V5 传感器护罩并将它们卡在一起。
- 将连接的 UNO/传感器板放入机器人中心内的夹子支架中。
- 用双面胶带将电机驱动器放在左侧内壁,将蓝牙适配器放在右侧壁上。
第 8 步:接线 - 电机
- 电机驱动器上的 A-1A 引脚连接到传感器屏蔽上的引脚 5
- 电机驱动器上的 A-1B 引脚连接到传感器屏蔽上的引脚 6
- 电机驱动器上的 B-1A 引脚到传感器屏蔽上的引脚 3
- 电机驱动器上的 B-1B 引脚到传感器屏蔽上的引脚 11
现在让机器人正面远离你,拿起左侧的电线 -
- 将左侧的两根黑色电线连接到电机 A 的第一个输出螺钉端子
- 将左侧的两根红线连接到电机 A 的第二个输出螺钉端子
拿起右侧的电线 -
- 将左侧的两根黑色电线连接到电机 B 的第一个输出螺钉端子
- 将左侧的两根红线连接到电机 B 的第二个输出螺钉端子
伺服器:
- 现在将 Y 伺服线连接到传感器屏蔽上的引脚线 2。白色或橙色线始终是信号线。
- 现在将 X(夹具)伺服线连接到传感器屏蔽上的引脚线 7。白色或橙色线始终是信号线。
步骤 9:为蓝牙模块接线
- 蓝牙适配器 Tx -> 传感器屏蔽引脚 0
- 蓝牙适配器 Rx -> 传感器屏蔽引脚 1
第 10 步:添加电源
将 5 'aa'(或其他 6v 电池组)电池组的电源线连接到传感器屏蔽的电源螺丝端子:
- 红色到 Vcc
- 黑色到地
- 接下来确保 V5 传感器屏蔽上的跳线在跳线针上就位。
- 将 L9110s 驱动器上的 GND 引脚连接到传感器屏蔽上的 GND 引脚。
- 将 6v 或 7.2v 电池或您为电机选择的其他电池的正极线连接到 L9110S 电机驱动器上的 Vcc 引脚。
- 将电机电池的负极 (GND) 线连接到电机屏蔽上的 GND 引脚。
第 11 步:配置 HC05/HC06 蓝牙模块
现在,您需要从操作系统的“控制”或“系统”面板进入 PC 上的蓝牙设备设置,或使用 Google 提供帮助。
可能的操作系统蓝牙设置信息:
- 窗户
- Linux(我在 Linux Mint 上使用 blueman,但请参阅您的发行版以获取更多信息)
- 苹果
您需要记下分配给它的串行端口设备名称或编号。
第 12 步:加载代码
检查并重新检查接线 ,是时候加载代码了。按照 Arduino 站点上有关如何安装 Arduino IDE 的说明进行操作。
安装 IDE 后,您可以接下来安装 L9110 电机驱动程序库。为此,请下载第 1 步中包含的名为 L9110Driver.zip 的 zip 文件并将其解压缩到您的 Arduino 库文件夹,或按照有关如何添加库的说明进行操作。
现在已经安装了 IDE 和电机驱动程序库,将机器人代码从步骤 1 中名为 blue_t_slave.zip 的 zip 文件加载到 Arduino IDE 中。这些文件也包含在此步骤中。
使用 USB 电缆将您的 PC 和 Arduino 连接起来。现在从 IDE 的 Tools->Board 菜单中选择板,这个项目的 Uno(如果与 Uno 不同,则选择您拥有的板)现在从 Tools->Port 菜单中,选择您的 com 端口。完成后,单击上传按钮。如果一切顺利,则代码已加载,如果没有,请参阅此处获取有关 IDE 和相关问题的帮助。
第 13 步:运行 Python 控制应用程序
要运行 Python 远程控制应用程序,请下载此步骤中的 zip 文件并将其解压缩到要运行它的位置。接下来,打开命令外壳(即终端、cmd.exe 等)并导航到您将文件解压缩到的目录。现在输入:python rover.py 从命令行和一个看起来像图像中的窗口应该弹出。如果没有,请查找任何 Python 错误并进行更正(即缺少库等...)如果需要,Python 站点可能会有所帮助。
应用程序运行后,您应该准备好了。
现在,打开机器人电源。然后键入适配器的通信端口并单击“连接”按钮。几秒钟后,您应该会看到其他控件已启用且连接按钮已禁用。这意味着您已连接到机器人。如果您无法连接到蓝牙适配器,您将不得不使用 Google 的魔法来帮助您!
控制应用程序使用简单,允许鼠标或键盘控制。
键盘控制是:
- 箭头为前进、后退、左转 90 度、右转 90 度
- a - 左转 45 度
- s - 右转 45 度
- h - 停止(停止)
- y - 设置夹具 Y 轴
- u - 设置夹具打开/关闭
- c - 抓手主页
Forward 和 Reverse 命令是恒定的,即它们在执行后保持机器人移动,直到发送新的方向或 Halt 命令。
90 度和 45 度转弯是暂时的,即经过一些延迟后,它们会阻止机器人移动。
夹具滑块不会自动在机器人上设置夹具。您必须点击相应的“设置”按钮或键才能实际执行设置。
滑块值的范围为 0-180。
- Gripper Y 轴:0 是一直向上,180 是一直向下。
- Gripper Open/Close:0 表示完全关闭,180 表示完全打开。
使用“断开连接”按钮停止使用该程序。这将发送命令以停止机器人并将抓手归位。
代码
- Python 驱动程序界面
- 流动站代码
Python 驱动程序 GUIPython
#!/usr/bin/env python## 对于 Linux、BSD 或 Mac OSX,您可以在此脚本上 chmod +x 以使其可执行############# Rover 控制应用程序##由 Scott Beasley 撰写 - 2015# 免费使用或修改。享受。############import sysimport serialimport timefrom Tkinter import *import tkFontimport tkMessageBox# 为应用程序类 App (Frame) 创建窗口:# 使窗口 def createWidgets (self):self.connected =False self.message =StringVar ( ) # 为抓手设置按钮制作一个小字体。 helv6 =tkFont.Font (family ='Helvetica', size =6, weight ='normal') self.frame =Frame (self.master) self.frame.pack() self.f1 =Frame (self.frame) self .l1 =Label (self.f1, text ="Comm Port:") self.l1.pack (side =LEFT) self.comm_entry =Entry (self.f1, bd =5, name ="comm_entry") self.comm_entry .pack (side =LEFT) self.connectButton =Button (self.f1, text ="Connect", command =self.SerialConnect, name ="b_connect") self.connectButton.pack (side =LEFT) self.disconnectButton =Button (self.f1, text ="Disconnect", command =self.SerialDisconnect, name ="b_disconnect") self.disconnectButton.pack (side =RIGHT) self.f1.grid (row =0, column =0) self.f2 =LabelFrame (self.frame, bd =3, 浮雕 ="groove", text="Ground Control") self.g_vert_fm =Frame (self.f2) self.grip_vert =Scale (self.g_vert_fm, from_ =0, to =180) self.grip_vert.grid (row =0, column =0, rowspan =4, sticky =W) self.grip_vert_set =Button (self.g_vert_fm, text ="Set", command =self.GripperY, name ="b_grip_vert_set", width =1, height =2, font =helv6) self.grip_vert_set.grid (row =5, column =0, sticky =W) self.master.bind ("", self.GripperY) self. g_vert_fm.grid (row =0, column =0, rowspan =4,sticky =W) self.leftforwardButton =Button (self.f2, text ="\\", command =self.TurnLeft45, name ="b_left_forward") self .leftforwardButton.grid (row =0, column =1) self.master.bind ("", self.TurnLeft45) self.leftButton =Button (self.f2, text ="<", command =self.TurnLeft, name ="b_left") self.leftButton.grid (row =1, column =1) self.master.bind (" ", self.TurnLeft ) self.rightforwardButton =Button (self.f2, text ="/", command =self.TurnRight45, name ="b_right_forward") self.rightforwardButton.grid (row =0, column =3) self.master.bind (" ", self.TurnRight45) self.haltButton =Button (self.f2, text ="Halt!", command =self.Halt, name ="b_halt") self.haltButton .grid (row =1, column =2) self.master.bind ("", self.Halt) self.rightButton =Button (self.f2, text=">", command =self.TurnRight, name ="b_right") self.rightButton.grid( row =1, column =3) self.master.bind (" ", self.TurnRight) self.upButton =Button (self.f2, text="^", command =self.Forward, name ="b_forward") self.upButton.grid (row =0, column =2) self.master.bind (" ", self.Forward) self.leftdownButton =Button (self.f2, text ="/", command =self.TurnRight45, name ="b_left_down") self.leftdownButton.grid (row =2, column =1) self.downButton =Button (self. f2, text="V", command=self.Reverse, name ="b_reverse") self.downButton.grid (row=2, column =2) self.master.bind (" ", self.Reverse) self.f2.grid (row =1, column =0, pady =25) self.rightdownButton =Button (self.f2, text ="\\", command =self.TurnLeft45, name ="b_right_down") self.rightdownButton.grid (row =2, column =3) self.g_horz_fm =Frame (self.f2) self.grip_horz =Scale (s elf.g_horz_fm, from_ =0, to =180, orient =HORIZONTAL) self.grip_horz.grid (row =0, column =0, columnspan =7, sticky =E) self.grip_horz_set =Button (self.g_horz_fm, text ="set", command =self.GripperX, name ="b_grip_horz_set", width =1, height =2, font =helv6) self.grip_horz_set.grid (row =0, column =8) self.master.bind ("", self.GripperX) self.g_horz_fm.grid (row =4, column =0, columnspan =7, sticky =E) self.master.bind (" ", self.GripperHome) self.f3 =Frame (self.frame) self.l2 =Label (self.f3, text ="Last action:") self.l2.pack (side =LEFT) self.l3 =Label (self.f3, text=" ", textvariable =self.message) self.l3.pack (side =RIGHT) self.f3.grid (row =3, column =0, pady =8) #设置机器人控制按钮的状态。连接时启用,#否则禁用。 def CtrlButtonsState (self, bstate):self.leftforwardButton.config (state =bstate) self.leftButton.config (state =bstate) self.rightforwardButton.config (state =bstate) self.rightButton.config (state =bstate) self. upButton.config (state =bstate) self.leftdownButton.config (state =bstate) self.downButton.config (state =bstate) self.rightdownButton.config (state =bstate) self.haltButton.config (state =bstate) self. disconnectButton.config (state =bstate) self.grip_horz.config (state =bstate) self.grip_vert.config (state =bstate) self.grip_horz_set.config (state =bstate) self.grip_vert_set.config (state =bstate) # 设置通信端口条目的状态。未连接时启用,# bot 连接时禁用。 def ConnCtrlsState (self, bstate):self.connectButton.config (state =bstate) self.comm_entry.config (state =bstate) # 连接到comm 输入字段中输入的comm 端口。 def SerialConnect (self):try:# 在这里更改波特率 if diffrent then 9600 self.ser =serial.Serial (self.comm_entry.get (), 9600) except IOError:tkMessageBox.showerror ("Invalid comm port", "未找到通信端口。") return self.ConnCtrlsState (DISABLED) self.CtrlButtonsState (NORMAL) self.message.set ("SerialConnect") self.connected =True time.sleep (3) # 稍作停留以进行连接# 断开与机器人的连接(关闭通信端口)。 def SerialDisconnect (self):try:# 发送 Halt 命令,以防机器人仍在移动。 self.send_cmd ('h', "Halt!") time.sleep (1) self.ser.close () 除了 IOError:print "Could not close port..." self.message.set ("SerialDisconnect") self .ConnCtrlsState (NORMAL) self.CtrlButtonsState (DISABLED) self.connected =False time.sleep (2) # 等待断开连接发生 # 发送命令到开放的通信端口 def send_cmd (self, action, msg):if self.connected ==True:for val in action:self.ser.write (val) self.ser.flush () self.message.set (msg) # 向机器人发送左转命令。 def TurnLeft (self, event =None):self.send_cmd ('a', "Left") # 向机器人发送一个左转命令。 def TurnLeft45 (self, event =None):self.send_cmd ('q', "Left45") # 向机器人发送右转命令。 def TurnRight (self, event =None):self.send_cmd ('s', "Right") # 向机器人发送一个右转命令。 def TurnRight45 (self, event =None):self.send_cmd ('e', "Right45") # 向机器人发送转发命令。 def Forward (self, event =None):self.send_cmd ('w', "Up") # 向机器人发送反向命令。 def Reverse (self, event =None):self.send_cmd ('z', "Down") # 向机器人发送暂停命令。 def Halt (self, event =None):self.send_cmd ('h', "Halt!") # 设置抓手(X)。 def GripperX (self, event =None):# 读取滑块控件并将值发送到机器人控制器 # 注意:0 表示一直关闭,180 表示一直打开 grp_change =('>', chr (self. Gripper_horz.get()), chr(255)) self.send_cmd (grp_change, "Gripper X") # 设置夹持器 Y. def GripperY (self, event =None):# 读取滑块控件并将值发送到bot controller # 注意:0 是一路向上,180 是一路向下 grp_change =('^', chr (self.grip_vert.get ( )), chr (255)) self.send_cmd (grp_change, "Gripper Y ") # 将夹具设置到“原位”位置。 def GripperHome (self, event =None):self.send_cmd (('c', chr (255)), "Gripper Home") def __init__ (self, master =None):Frame.__init__ (self, master) self. pack ( ) self.createWidgets ( ) self.CtrlButtonsState (DISABLED)# 启动 GUI (Tk) 然后调整应用程序的大小和标题 windowdef main ( ):root =Tk ( ) root.geometry ("450x350") root.wm_title ( "Rover Control Center (RCC)") app =App (master =root) app.mainloop ( )if __name__ =='__main__':main ( )
Rover 代码Arduino
/* 蓝牙漫游器。人生目标... 听从你的命令,通过空气神奇地发送!或来自 USB :) 由 Scott Beasley 撰写 - 2015 年免费使用或修改。享受。*//* 使用 L9110S 库。它与 L9110S h 桥配合使用。从 https://github.com/jscottb/L9110Driver 下载或从 https://github.com 克隆 zip 以从存档文件名中删除“-master”以添加库*/#include#include #define SERVO_Y 2 // 夹针 Y 伺服#define SERVO_CLAW 7 // 夹针夹爪伺服#define pinAIN1 5 // 定义 I1 接口#define pinAIN2 6 // 定义 I2 接口#define pinBIN1 3 / / 定义 I3 接口#define pinBIN2 11 // 定义 I4 接口// 速度定义#define MAXFORWARDSPEED 225 // 我们想要前进的最大速度#define MAXBACKWARDSPEED 225 // 最大反向速度#define TOPSPEED 255 // 用于帮助更好地打开地毯和较粗糙的表面。// 用于驱动和伺服的各种时间延迟#define TURNDELAY 475#define TURNDELAY45 235#define BACKUPDELAY 400#define SERVOMOVEDELAY 200#define SERVOSEARCHDELAY 85/* 全局区域。*/// 创建电机、伺服对象与L9110_Motor motor_left(pinAIN1,pinAIN2)接口; // 创建左电机对象L9110_Motor motor_right (pinBIN1, pinBIN2); // 创建右电机对象Servo Grip_y_servo; // 为夹持器 Y 轴创建伺服对象 Grip_servo; // 为夹持器爪空设置创建一个伺服对象 ( ){ // 如果与 9600 Serial.begin (9600) 不同,请在此处更改波特率; Grip_y_servo.attach (SERVO_Y); // 附加舵机SERVO_LR Grip_y_servo.write (90);夹子伺服.attach(SERVO_CLAW); // 附加舵机SERVO_LR Grip_servo.write (90);延迟(500);}无效循环(){字节命令=0,val =0; if (Serial.available ( )> 0) { // 读取传入的命令字节 command =Serial.read ( ); } switch (command) { case 'w':go_forward(); //Serial.println("前进");休息; case 'z':go_backward(); //Serial.println("倒退");休息;案例'a':go_left();延迟(TURNDELAY);停 ( ); //Serial.println("左转");休息; case 's':go_right();延迟(TURNDELAY);停 ( ); //Serial.println("右转");休息; case 'q':go_left();延迟(TURNDELAY45);停 ( ); //Serial.println("左转");休息;案例'e':go_right();延迟(TURNDELAY45);停 ( ); //Serial.println("右转");休息;案例'h':停止(); //Serial.println("暂停");休息; case '>':// 夹爪 X 移动发送伺服设定值 val =Serial.read ( ); // 我们将值限制为设置的实际移动限制。 Grip_servo.write (constrain (val, 64, 179)); //Serial.println("GripperX");休息; case '^':// 夹爪 Y 移动发送伺服设定值 val =Serial.read ( ); // 我们将值限制为设置的实际运动限制。 Grip_y_servo.write (constrain (val, 53, 179)); //Serial.println("GripperY");休息; case 'c':// 我们将值限制为设置的实际移动限制 Grip_y_servo.write (90);抓地伺服.写(90); //Serial.println("GripperHome");休息; case 255:// 在所有夹持器命令之后发送 Serial.flush ( );休息;串行刷新(); delay(125);}void go_forward(){ //Serial.println ("Going forward..."); // 将电机加速到速度。 // 帮助在某些表面上旋转,并在 GM 的斜坡上清扫和去皮_it (MAXFORWARDSPEED, FORWARD, FORWARD); // 设置为所有设置的速度,以防最后一个斜坡不是全部 // 它。 motor_left.setSpeed (MAXFORWARDSPEED); motor_right.setSpeed (MAXFORWARDSPEED); motor_left.run (前进|释放); motor_right.run (FORWARD|RELEASE);}void go_backward(){ //Serial.println ("Going back..."); // 将电机加速到速度。 // 帮助在某些表面上旋转,并在 GM 的斜坡上清扫和去皮_it (MAXBACKWARDSPEED, BACKWARD, BACKWARD); // 设置为所有设置的速度,以防最后一个斜坡不是全部 // 它。 motor_left.setSpeed (MAXBACKWARDSPEED); motor_right.setSpeed (MAXBACKWARDSPEED); motor_left.run (向后|释放); motor_right.run (BACKWARD|RELEASE);}void go_left (){ //Serial.println ("Going left..."); // 将电机加速到速度。 //帮助在某些表面上旋转并在GM的ramp_it(TOPSPEED,BACKWARD,FORWARD)上清洁和去皮; // 设置为所有设置的速度,以防最后一个斜坡不是全部 // 它。 motor_left.setSpeed (TOPSPEED); motor_right.setSpeed (TOPSPEED); motor_left.run (向后|释放); motor_right.run (FORWARD|RELEASE);}void go_right(){ //Serial.println ("向右走..."); // 将电机加速到速度。 //帮助在某些表面上旋转并在GM的ramp_it(TOPSPEED,FORWARD,BACKWARD)上清洁和去皮; // 设置为所有设置的速度,以防最后一个斜坡不是全部 // 它。 motor_left.setSpeed (TOPSPEED); motor_right.setSpeed (TOPSPEED); motor_left.run (前进|释放); motor_right.run (BACKWARD|RELEASE);}voidhalt(){ //Serial.println ("Halt!"); //ramp_it (0, BRAKE, BRAKE); motor_left.setSpeed (0); motor_right.setSpeed (0); motor_left.run (BRAKE); motor_right.run (BRAKE);}voidramp_it (uint8_t speed, uint8_t lf_dir, uint8_t rt_dir){ uint8_tramp_val =0, step_val =0; step_val =abs(速度/4); if (!speed) step_val =-step_val; for (uint8_t i =0; i <4; i++) {ramp_val +=step_val; motor_left.setSpeed (ramp_val); motor_right.setSpeed (ramp_val); motor_left.run (lf_dir|RELEASE); motor_right.run (rt_dir|RELEASE);延迟(25); }}
L9110 驱动程序
L9110 Arduino 电机驱动器https://github.com/jscottb/L9110Driver定制零件和外壳
4wdgripperbt2.fzz示意图
4wdgripperbt2.fzz制造工艺