Skip to content

Files

Latest commit

Dec 21, 2025
091a9b7 · · Dec 21, 2025

History

History
457 lines (339 loc) · 12.3 KB

File metadata and controls

457 lines (339 loc) · 12.3 KB

The-Best-Hand

Poker AMD Prototype Keywords PLS RECOMMEDN AND STAR

#Journals: We have decided to make a poker arm robot!!!

Prelimenary research: We have been researching what features we want, here is what we came up with: Plays poker, once it sees its hand it will play the game normally We want to use a Gemini API to determine the best move to make, (check/call, raise, or fold), then based on that, run predetermined moves that we model out. We also thought it would be fun to have a "Poker Face", a 180x126 TFT LCD display depicting the model's emotions and current actions at all times.mes.


Setup and Usage Guide

Hardware Requirements

Component Description Purpose
SO-Arm100 6-DOF robotic arm Physical poker actions
Arduino Uno Elegoo R3 Microcontroller TFT display + Button input
Adafruit ST7735 TFT LCD 1.8" 160x128 display Poker face display
3x Momentary Push Buttons Tactile switches Check/Call, Fold, Raise inputs
USB Cameras (x1) 1080p webcam Game state capture (video2)
Computer Linux/macOS/Windows Main controller

Circuit Assembly Instructions

TFT Display Controller (Arduino Uno Elegoo R3)

Wire the Adafruit ST7735 TFT LCD to the Arduino Uno Elegoo R3 using SPI:

TFT LCD              Arduino Uno Elegoo R3
-------              ---------------------
CS         ------>   Pin 10 (SS)
RST        ------>   Pin 9
DC         ------>   Pin 8
MOSI       ------>   Pin 11 (MOSI)
SCK        ------>   Pin 13 (SCK)
VCC        ------>   5V
GND        ------>   GND
LED (optional) --->  5V (or Pin 6 for PWM brightness control)
PWM brightness control)
control)

Note: The TFT display uses the hardware SPI pins on the Arduino Uno. Make sure to connect MOSI (Pin 11) and SCK (Pin 13) correctly.

Required Arduino Libraries:

  • Adafruit GFX Library
  • Adafruit ST7735 Library

Upload the Arduino sketch from arduino/seeed_led_controller/seeed_led_controller.ino.

Button Controller

Wire three buttons to the Arduino Uno Elegoo R3:

Buttons             Arduino Uno Elegoo R3
-------             ---------------------
Check/Call ------>  Pin 2 (one terminal to Pin 2, other to GND)
Fold       ------>  Pin 3 (one terminal to Pin 3, other to GND)
Raise      ------>  Pin 4 (one terminal to Pin 4, other to GND)
 to GND)
ND)

Note: Internal pull-up resistors are used. No external resistors needed.

Upload the Arduino sketch from arduino/button_controller/button_controller.ino.

Complete Wiring Diagram

                    +------------------+
                    |     Computer     |
                    +--------+---------+
                             |
              +--------------+---------------+
              |              |               |
    +---------+---+   +------+------+--------+
    | USB Camera  |   | Arduino Uno |
    | (video2)    |   | Elegoo R3   |
    +-------------+   +------+------+
                             |
                   +---------+---------+
                   |                   |
            +------+------+     +------+------+
            | ST7735 TFT  |     | 3 Push      |
            | LCD Display |     | Buttons     |
            +-------------+     +-------------+
+-------------+

Software Installation

1. Clone and Setup

git clone https://github.com/Eventide-03/The-Best-Hand.git

cd The-Best-Hand


# Run setup script
chmod +x setup.sh
./setup.sh



# Or manually:
python -m venv venv

source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -r requirements.txtt

2. Configure Environment

cp .env.example .env

# Edit .env with your settings:

# - GEMINI_API_KEY=your_api_key_here

# - LED_SERIAL_PORT=/dev/ttyACM0

# - BUTTON_SERIAL_PORT=/dev/ttyACM1

3. Get Gemini API Key

  1. Go to Google AI Studio
  2. Click "Create API Key"
  3. Copy the key to your .env file

Training Models

Models are trained using LeRobot's imitation learning workflow:

1. Record Demonstrations

Use LeRobot's recording tools to capture demonstrations of poker actions:

  • check_call: Tapping the table gesture
  • raise: Pushing chips forward
  • fold: Pushing cards away

2. Train in Jupyter

Create a Jupyter notebook and train your policy:

from lerobot.common.policies.act.modeling_act import ACTPolicy

from safetensors.torch import save_file

import torch


# Train your policy

# ... training code ...


# Save as safetensors (recommended)

save_file(policy.state_dict(), "models/check_call.safetensors")


# Or save as TorchScript (legacy)

torch.jit.save(torch.jit.script(policy), "models/check_call.pth")

3. Model Storage Options

Option A: HuggingFace Hub (Recommended)

Upload models to HuggingFace Hub and the system will download them automatically:

from src.arm_controller import ArmController


# Models are downloaded from HuggingFace Hub

controller = ArmController(hf_repo_id="username/poker-arm-models")

controller.initialize()

Option B: Local Files

Place model files in the models/ directory:

  • models/check_call.safetensors (recommended)
  • models/raise.safetensors
  • models/fold.safetensors
  • models/chip_management.safetensors

Or use legacy .pth format:

  • models/check_call.pth
  • models/raise.pth
  • models/fold.pth
  • models/chip_management.pth

See models/README.md for model format details.

Running Test Files

Test Button Input

# Activate virtual environment

source venv/bin/activate


# List available serial ports
python -m scripts.test_buttons --list



# Run button simulation tests (no hardware needed)
python -m scripts.test_buttons --test



# Test turn manager logic
python -m scripts.test_buttons --turns



# Interactive button test (with or without hardware)
python -m scripts.test_buttons --interactivee

Test LED Matrix Faces

# List available serial ports
python -m scripts.test_led --list



# Test all emotes
python -m scripts.test_led --emotes



# Run all TFT display tests
python -m scripts.test_led --test



# Interactive TFT display test
python -m scripts.test_led --interactivee

Test Model Loading

# Check PyTorch installation and models directory
python -m scripts.test_models --check



# Create a sample model for testing
python -m scripts.test_models --create-sample



# Test arm actions in simulation
python -m scripts.test_models --actions



# Run all model tests
python -m scripts.test_models --testt

Test Gemini API

# Test API connection
python -m scripts.test_gemini --connection



# Test poker decision making
python -m scripts.test_gemini --decision



# Interactive Gemini test
python -m scripts.test_gemini --interactive



# Run all Gemini tests
python -m scripts.test_gemini --testt

Test Cameras

python -m scripts.test_cameras

Test Robotic Arm

# Run in simulation mode
python -m scripts.test_arm --test



# Check hardware connection
python -m scripts.test_arm --check



# Interactive arm test
python -m scripts.test_arm --interactivee

Running the Game

Start the Poker Robot

source venv/bin/activate
python -m src.mainn

Game Flow

  1. The game starts with configurable number of players (default: 3, including robot)
  2. Each player starts with $150
  3. Human players press buttons to indicate their action:
    • Check/Call button
    • Fold button
    • Raise button ($10 fixed raise)
  4. After all human players have acted, the robot:
    • Captures images from cameras
    • Sends game state + complete betting history to Gemini API
    • Receives and executes the recommended action
  5. The TFT display shows the robot's "emotion" and current action
  6. The robotic arm performs the physical action

Configuration

Edit config/arm_config.yaml to adjust:

  • game.player_count: Number of players (default: 3)
  • game.starting_chips: Starting chips (default: 150)
  • game.raise_amount: Fixed raise amount (default: 10)

Gameplay Loop Guide

This section provides a detailed walkthrough of how to run and test the complete gameplay loop.

Prerequisites

  1. Hardware Setup Complete: Arduino Uno Elegoo R3 connected with ST7735 display and buttons wired correctly
  2. Arduino Sketches Uploaded: Both display and button controller sketches uploaded
  3. Camera Connected: USB camera available at /dev/video2
  4. Environment Configured: .env file with GEMINI_API_KEY set

Step 1: Verify Hardware Connections

# Check if Arduino is detected
ls /dev/ttyACMM* /dev/ttyUSB*


# Check if camera is available
ls /dev/videoo*

Step 2: Test Individual Components

# Activate virtual environment

source venv/bin/activate


# Test button inputs
python -m pytest tests/test_gameplay_loop.py -v -k  "button"


# Test camera capture
python -m pytest tests/test_camera_gemini.py -v -k  "camera"


# Test LED display faces
python -m pytest tests/test_led_faces.py -vv

Step 3: Run the Complete Gameplay Loop

# Start the main game
python -m src.mainn

During gameplay:

  1. The TFT display shows "READY" when initialized
  2. Wait for human players to press buttons (Check/Call, Fold, or Raise)
  3. System prints confirmations for each button press:
    [1/2] Button pressed: check_call
    [2/2] Button pressed: raise
    >>> Robot's turn! <<<
    urn! <<<
    ;
    
  4. Robot captures image from camera, sends to Gemini, gets decision
  5. TFT display shows emotion (happy 😊, sad 😢, or confident 😎) based on decision
  6. Robot executes the action

Step 4: Test Mode (Without Full Hardware)

For testing without all hardware connected:

# Run gameplay loop test (simulated buttons)
python -m pytest tests/test_gameplay_loop.py -v



# Test camera and Gemini integration
python -m pytest tests/test_camera_gemini.py -v



# Test model loading
python -m pytest tests/test_model_loading.py -vv

Understanding Button Press Output

When buttons are pressed, you'll see confirmation output like:

==================================================
WAITING FOR HUMAN PLAYERS
Players: 3 (including robot)
Pot: $0
Waiting for 2 button presses...
==================================================
  Player 1: check_call
  Player 2: raise

>>> Robot's turn! <<<

Decision: call (confidence: 0.75)
Reasoning: Pot odds are favorable with current hand strength
ent hand strength
nd strength

TFT Display Faces

The display shows different faces based on the robot's state:

  • Happy Face 😊: Confident decision, winning
  • Sad Face 😢: Folding, losing
  • Thinking Face 🤔: Processing decision
  • Excited Face 🎉: Raising, aggressive play
  • buttons.enabled: Enable/disable hardware buttons

Project Structure

The-Best-Hand/
├── arduino/
│   ├── seeed_led_controller/   # TFT display Arduino code
│   └── button_controller/      # Button input Arduino code
├── config/
│   └── arm_config.yaml         # Main configuration file
├── models/                     # Trained PyTorch models
├── scripts/
│   ├── test_arm.py            # Arm controller tests
│   ├── test_buttons.py        # Button input tests
│   ├── test_cameras.py        # Camera tests
│   ├── test_gemini.py         # Gemini API tests
│   ├── test_led.py            # TFT display tests
│   └── test_models.py         # Model loading tests
├── src/
│   ├── arm_controller.py      # Robotic arm control
│   ├── button_input.py        # Button input handling
│   ├── camera_manager.py      # Camera capture
│   ├── game_state.py          # Game state tracking
│   ├── gemini_client.py       # Gemini API client
│   ├── led_controller.py      # TFT display control
│   └── main.py                # Main entry point
└── tests/                     # Unit tests
         # Unit tests

Troubleshooting

"No serial ports found"

  • Check USB connections
  • Run ls /dev/tty* (Linux/macOS) to see available ports
  • On Windows, check Device Manager for COM ports

"Button presses not detected"

  • Verify Arduino code is uploaded
  • Check button wiring (one terminal to pin, other to GND)
  • Test with python -m scripts.test_buttons --list

"Gemini API error"

  • Verify API key in .env
  • Check internet connection
  • Test with python -m scripts.test_gemini --connection

"Model loading failed"

  • Ensure PyTorch is installed: pip install torch
  • Check model file format (TorchScript or full model)
  • Test with python -m scripts.test_models --check