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.
| 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 |
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.
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.
+------------------+
| Computer |
+--------+---------+
|
+--------------+---------------+
| | |
+---------+---+ +------+------+--------+
| USB Camera | | Arduino Uno |
| (video2) | | Elegoo R3 |
+-------------+ +------+------+
|
+---------+---------+
| |
+------+------+ +------+------+
| ST7735 TFT | | 3 Push |
| LCD Display | | Buttons |
+-------------+ +-------------+
+-------------+
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.txttcp .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- Go to Google AI Studio
- Click "Create API Key"
- Copy the key to your
.envfile
Models are trained using LeRobot's imitation learning workflow:
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
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")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.safetensorsmodels/fold.safetensorsmodels/chip_management.safetensors
Or use legacy .pth format:
models/check_call.pthmodels/raise.pthmodels/fold.pthmodels/chip_management.pth
See models/README.md for model format details.
# 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# 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# 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 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 --testtpython -m scripts.test_cameras# 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 --interactiveesource venv/bin/activate
python -m src.mainn- The game starts with configurable number of players (default: 3, including robot)
- Each player starts with $150
- Human players press buttons to indicate their action:
- Check/Call button
- Fold button
- Raise button ($10 fixed raise)
- 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
- The TFT display shows the robot's "emotion" and current action
- The robotic arm performs the physical action
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)
This section provides a detailed walkthrough of how to run and test the complete gameplay loop.
- Hardware Setup Complete: Arduino Uno Elegoo R3 connected with ST7735 display and buttons wired correctly
- Arduino Sketches Uploaded: Both display and button controller sketches uploaded
- Camera Connected: USB camera available at
/dev/video2 - Environment Configured:
.envfile withGEMINI_API_KEYset
# Check if Arduino is detected
ls /dev/ttyACMM* /dev/ttyUSB*
# Check if camera is available
ls /dev/videoo*# 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# Start the main game
python -m src.mainnDuring gameplay:
- The TFT display shows "READY" when initialized
- Wait for human players to press buttons (Check/Call, Fold, or Raise)
- System prints confirmations for each button press:
[1/2] Button pressed: check_call [2/2] Button pressed: raise >>> Robot's turn! <<< urn! <<< ; - Robot captures image from camera, sends to Gemini, gets decision
- TFT display shows emotion (happy 😊, sad 😢, or confident 😎) based on decision
- Robot executes the action
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 -vvWhen 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
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
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
- Check USB connections
- Run
ls /dev/tty*(Linux/macOS) to see available ports - On Windows, check Device Manager for COM ports
- Verify Arduino code is uploaded
- Check button wiring (one terminal to pin, other to GND)
- Test with
python -m scripts.test_buttons --list
- Verify API key in
.env - Check internet connection
- Test with
python -m scripts.test_gemini --connection
- Ensure PyTorch is installed:
pip install torch - Check model file format (TorchScript or full model)
- Test with
python -m scripts.test_models --check