5-DOF Robot Arm

Introduction

This is a hobby project where I designed and built a custom 5-DOF 3D printed robot arm, as well as a graphical user interface (GUI) to control the robot arm. The purpose is to explore communication protocols, robot kinematics (D-H method), and learn software design patterns (among many other concepts). This project is still very much a work in progress; I have many features in mind.

Table of Contents

Hardware

  • All 3D printed parts are PLA
  • Feetech STS3215 (30kg) serial bus servo motors
    • These provide more control and feedback than traditional hobby servo motors which often only allow position control (no feedback at all). The serial bus servo motors can be daisy-chained using cables with Molex 5264 connectors, which reduce the amount of wiring clutter.
  • The low-level control of the motors is programmed on an ESP32 module using Feetech's Arduino libraries.
  • The communication server and the client run on an N95 mini PC.
    • I will explore ways to increase the efficiency of the computations to be able to run it on a Raspberry Pi.

Software

The backend consists of:

  • Socket server
  • Message handler
  • Protocol parser
  • Robot class (high level control library)
  • Kinematics class (computation library)
  • SQLite database and interface
  • Saved positions handler

The frontend GUI application is written using the Qt framework and designed using Qt Creator. A 3rd party library, breeze, was used for styling.

High-Level Project Architecture - Binary Protocol

I wrote a binary protocol to manage the communication between the Python server and the C++ client via TCP connection. The server and client communicate using streams of byte arrays that contain various pieces of information such as the type of message being sent (CONNECT, HOME, DISABLE, MOVE_X, etc.) and the payload (such as Cartesian coordinates or joint angles). They share a common set of definitions that they both understand, which makes this system language-agnostic.

Global Definitions

  • The message type values mirror each other on both the client and server side.
  • Both sides expect a byte array "frame" of length 64.

Robot/Server Side (Python)

  • A socket server listens for incoming messages. When messages are received, the socket server continues to accumulate bytes until the buffer is full (64 bytes).
  • The message is passed to a MessageHandler class, which calls a decode_message method from the ProtocolParser class to extract the message type and payload, then the MessageHandler class calls the message_handler method that corresponds to the message type that was received.
  • To send messages (such as joint angle feedback and message responses) to the client, an encode_message method in the ProtocolParser class is used to convert the payload into a byte array
  • When positions are saved, they are stored in a serverless database and recalled by ID.

GUI/Client side (C++)

When debugging the robot, whether it was an incorrect computation in the kinematics, a communication issue, an uncalibrated servo, or some other issue, I found it very cumbersome to rely on reading a mess of print statements in the terminal to figure out why my robot was trying to fly away into infinity or smash itself. The original goal of the GUI was simply to provide a quick way to perform test motions on the robot arm and view feedback. As I built it, I added more and more features and even learned to build a binary protocol.

![alt text](image-2.png)

  • The client uses the same class architecture as the server.
  • A MessageHandler class is used to route messages based on the message type.
  • A ProtocolParser for encoding/decoding messages.
  • The Qt application uses a signal/slot mechanism to relate user interactions with functions. For example, sending a HOME command in the client will also emit a signal to read joint angles, and the GUI will react to this signal by populating/updating the joint angle values displayed in spinboxes.
  • A QTableView is used for teaching the robot. While the motors are disabled, you can move the robot to a position and save that position's Cartesian coordinates, which also saves the joint positions internally.
  • Positions can be recalled individually or in the sequence that they appear in the table.

Teaching

One of the side quests that came out of the GUI adventure was teaching the robot. I've seen this being used on industrial robots in the past, and I thought it would be an interesting learning experience to build it myself.

Kinematics

The kinematics of the robot arm were set up using the Denavit-Hartenberg (D-H) method, and solved analytically using basic trigonometry.