An AI-powered robotic flower picking and ordering system that combines natural language processing, computer vision, and robotic control to autonomously fulfill flower orders.
This system allows users to place flower orders in natural language through a chatbot web interface. The AI agent processes the order, generates a bill of materials from a Neo4j knowledge graph, and controls a UR5 robotic arm to physically pick and arrange the flowers.
π Repository: github.com/namanjain4463/Flower-Order-Assistant
- π€ AI-Powered Agent: LangChain ReAct agent with OpenAI GPT for natural language understanding
- π Semantic Search: Vector-based color matching for flexible order interpretation
- ποΈ Knowledge Graph: Neo4j database for order relationships and pickup/dropoff logic
- ποΈ Computer Vision: YOLO object detection for flower identification
- π¦Ύ Robotic Control: UR5 arm with real-time position correction
- π¬ Web Interface: Clean Streamlit chat interface with session history
- System Requirements
- Hardware Requirements
- Installation
- Configuration
- Running the Application
- Usage Guide
- Architecture
- Troubleshooting
- Development
- Python: 3.8 or higher
- Operating System: Linux (tested on Raspberry Pi OS/Ubuntu)
- Neo4j: Aura cloud instance or local Neo4j 5.x
- OpenAI API: Valid API key with GPT-4 access
See requirements.txt for the complete list. Main dependencies:
streamlit==1.35.0- Web interfacelangchain==0.3.9- Agent orchestrationlangchain-openai==0.2.10- OpenAI integrationlangchain-neo4j==0.1.1- Neo4j integrationneo4j==5.27.0- Database driveropenai==1.56.0- OpenAI API clientultralytics- YOLO object detectiontorch- Neural network inferenceopencv-python- Image processingpandas- Data handlingnumpy- Numerical operations
-
Universal Robots UR5 robotic arm
- IP Address: 169.254.152.222 (configurable in
robot_executor.py) - RTDE interface enabled
- IP Address: 169.254.152.222 (configurable in
-
USB Camera
- Resolution: 1280x720 or higher
- V4L2 compatible (Linux)
-
Servo Gripper
- Connected to GPIO pin 12
- Compatible with
gpiozerolibrary
-
Raspberry Pi or Linux Computer
- For robot control and GPIO access
- Connected to same network as UR5
- Monitor/Display - For viewing robot camera feed during operation
git clone https://github.com/namanjain4463/Flower-Order-Assistant.git
cd Flower-Order-Assistantpython3 -m venv venv
source venv/bin/activate # On Linux/Mac
# OR
.\venv\Scripts\Activate.ps1 # On Windows PowerShellpip install --upgrade pip
pip install -r requirements.txtFor camera and GPIO support:
sudo apt-get update
sudo apt-get install -y python3-opencv
sudo apt-get install -y v4l-utilsFor Raspberry Pi GPIO:
sudo apt-get install -y python3-gpiozero pigpio
sudo systemctl enable pigpiod
sudo systemctl start pigpiodEnsure these files are in the project root:
flower_joint_model_CLEAN.pth- MLP joint angle predictorbest_yolo_CLEAN.pt- YOLO flower detection model
Note: These models should be provided separately or trained using your specific setup.
Create .streamlit/secrets.toml in the project directory:
mkdir -p .streamlitEdit .streamlit/secrets.toml:
# OpenAI Configuration
OPENAI_API_KEY = "sk-your-openai-api-key-here"
OPENAI_MODEL = "gpt-4"
# Neo4j Configuration
NEO4J_URI = "neo4j+s://your-instance.databases.neo4j.io"
NEO4J_USERNAME = "neo4j"
NEO4J_PASSWORD = "your-neo4j-password"// Create Color nodes
CREATE (red:Color {name: 'red'})
CREATE (orange:Color {name: 'orange'})
CREATE (pink:Color {name: 'pink'})
CREATE (purple:Color {name: 'purple'})
CREATE (white:Color {name: 'white'})
// Create Order nodes (pickup sequence)
CREATE (o1:Order {name: '1'})
CREATE (o2:Order {name: '2'})
CREATE (o3:Order {name: '3'})
CREATE (o4:Order {name: '4'})
CREATE (o5:Order {name: '5'})
// Create EndLocation nodes (dropoff positions)
CREATE (locA:EndLocation {name: 'A'})
CREATE (locB:EndLocation {name: 'B'})
CREATE (locC:EndLocation {name: 'C'})
CREATE (locD:EndLocation {name: 'D'})
CREATE (locE:EndLocation {name: 'E'})
// Create relationships (example mapping)
MATCH (c:Color {name: 'red'}), (o:Order {name: '1'})
CREATE (c)-[:FOLLOWS_ORDER]->(o)
MATCH (c:Color {name: 'red'}), (loc:EndLocation {name: 'A'})
CREATE (c)-[:ENDS_AT]->(loc)
// Repeat for other colors...// Create vector index for semantic color search
CALL db.index.vector.createNodeIndex(
'flowerColorIndex',
'Color',
'embedding',
1536,
'cosine'
)You'll need to generate and store embeddings for each color using OpenAI's embedding model:
from langchain_openai import OpenAIEmbeddings
from neo4j import GraphDatabase
embeddings = OpenAIEmbeddings(openai_api_key="your-key")
colors = ['red', 'orange', 'pink', 'purple', 'white']
driver = GraphDatabase.driver(uri, auth=(username, password))
for color in colors:
embedding = embeddings.embed_query(color)
with driver.session() as session:
session.run(
"MATCH (c:Color {name: $name}) SET c.embedding = $embedding",
name=color,
embedding=embedding
)
driver.close()Edit robot_executor.py if needed:
# Line 18-19: Update UR5 IP address
UR_IP = "169.254.152.222" # Change to your robot's IP
# Lines 26-35: Adjust drop positions (in degrees)
DROP_POSITIONS = {
'A': [math.radians(x) for x in [80.52, -75.77, 88.12, -101.97, -93.01, 77.96]],
'B': [math.radians(x) for x in [70.00, -75.77, 88.12, -101.97, -93.01, 77.96]],
# ... adjust as needed for your workspace
}
# Line 23: Adjust camera position
P_CAM = [math.radians(x) for x in [-61.24, -89.61, 50.15, -57.46, -92.83, 115.69]]Test camera access:
# List available cameras
v4l2-ctl --list-devices
# Test camera capture
python3 -c "import cv2; cap = cv2.VideoCapture(0); print('Camera OK' if cap.isOpened() else 'Camera FAILED')"If using a different camera device:
# In robot_executor.py, line 148
cap = cv2.VideoCapture(0) # Change 0 to your camera indexpython3 test_connection.pyExpected output:
Connection successful!
streamlit run bot.pyThe app will open in your browser at http://localhost:8501
-
Place an Order:
I want 5 red and 3 white flowers -
Review BOM: The agent will display a Bill of Materials with pickup orders and dropoff locations.
-
Confirm:
yes -
Download CSV: After robot execution, download the generated bill of order CSV.
Simple Order:
User: I need 10 purple flowers
Agent: [Searches colors, generates BOM]
Here's your Bill of Materials:
- 10 purple flowers
- Pickup Order: 4
- Dropoff Location: D
Please confirm to proceed.
User: yes
Agent: [Creates CSV, executes robot]
CSV file created at: bill_of_order_abc123.csv
Robot Execution Summary: Picked 10 purple flowers
Multi-Color Order:
User: 3 red, 2 white, and 5 pink please
Agent: [Processes order]
Bill of Materials:
- 3 red (Pickup: 1, Drop: A)
- 2 white (Pickup: 5, Drop: E)
- 5 pink (Pickup: 3, Drop: C)
Confirm?
User: confirm
Agent: [Executes order]
Semantic Matching:
User: I want crimson and ivory flowers
Agent: [Vector search matches crimsonβred, ivoryβwhite]
How many of each color?
- π΄ Red
- π Orange
- π©· Pink
- π£ Purple
- βͺ White
Bill of Materials (BOM) includes:
color: Flower colorQuantity: Number requestedPickupOrder: Sequence number for robot pickingDropoffLocation: Where to place flowers (A-E)
Robot Execution Log shows:
- Successful picks
- Skipped items (if flower not found)
- Unavailable items summary
See ARCHITECTURE.md for detailed system architecture, component diagrams, and data flow documentation.
User βββΆ Streamlit UI βββΆ LangChain Agent βββΆ Tools
β
βββΆ Vector Search (Neo4j)
βββΆ BOM Generator (Cypher)
βββΆ Robot Executor (Subprocess)
β
βββΆ YOLO Detection
βββΆ MLP Joint Prediction
βββΆ UR5 Control
Cause: Missing or invalid secrets
Solution:
- Check
.streamlit/secrets.tomlexists - Verify all required keys are present
- Test Neo4j connection separately with
test_connection.py
Cause: PyTorch model loading error or robot connection failure
Solution:
# Test robot executor independently
echo '[{"color": "red", "quantity": 1, "pickupOrder": "1", "dropoffLocation": "A"}]' > test_input.json
python3 robot_executor.py test_input.json test_output.json
cat test_output.jsonCause: Camera not accessible or wrong index
Solution:
# List cameras
ls /dev/video*
# Test with different index
python3 -c "import cv2; cap = cv2.VideoCapture(1); print(cap.isOpened())"Cause: Embeddings not populated in Neo4j
Solution:
- Run the embedding population script (see Configuration step 2)
- Verify vector index exists:
SHOW INDEXES
Cause: Missing .pth or .pt model files
Solution:
- Ensure
flower_joint_model_CLEAN.pthis in project root - Ensure
best_yolo_CLEAN.ptis in project root - Check file permissions
Enable verbose logging:
# In agent.py, line 108
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # Already enabled - shows agent reasoning
return_intermediate_steps=True,
handle_parsing_errors=True
)chatbot/
βββ bot.py # Streamlit web interface
βββ agent.py # LangChain agent orchestration
βββ llm.py # OpenAI LLM & embeddings
βββ graph.py # Neo4j connection
βββ vector.py # Semantic color search
βββ cypher.py # Cypher queries & BOM generation
βββ robot_executor.py # UR5 robot control & vision
βββ utils.py # Helper functions
βββ test_connection.py # Neo4j connection test
βββ requirements.txt # Python dependencies
βββ .streamlit/
β βββ secrets.toml # Configuration (DO NOT COMMIT)
βββ README.md # This file
βββ ARCHITECTURE.md # System architecture documentation
-
Update Neo4j:
CREATE (c:Color {name: 'blue'}) MATCH (c:Color {name: 'blue'}), (o:Order {name: '6'}) CREATE (c)-[:FOLLOWS_ORDER]->(o) MATCH (c:Color {name: 'blue'}), (loc:EndLocation {name: 'F'}) CREATE (c)-[:ENDS_AT]->(loc)
-
Add Embedding:
embedding = embeddings.embed_query('blue') # Store in Neo4j
-
Update YOLO Model (if needed):
- Retrain with blue flower images
- Export new model
-
Add Drop Position (if needed):
# In robot_executor.py DROP_POSITIONS['F'] = [math.radians(x) for x in [...]]
# Test individual components
# 1. Neo4j connection
python3 test_connection.py
# 2. Vector search
python3 -c "from vector import vector_search_colors; print(vector_search_colors('crimson'))"
# 3. LLM connection
python3 -c "from llm import llm; print(llm.invoke('Hello'))"
# 4. Robot (dry run)
# Edit robot_executor.py to add test mode or use JSON filesexport OPENAI_API_KEY="sk-..."
export OPENAI_MODEL="gpt-4"
export NEO4J_URI="neo4j+s://..."
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="..."
streamlit run bot.py- Safety: Ensure robot workspace is clear before execution
- Calibration: KNN error compensator improves over time - initial accuracy may vary
- Concurrency: Current design handles one order at a time
- Storage: CSV files and images accumulate - clean periodically
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
For issues and questions:
- π Report bugs: GitHub Issues
- π Documentation: Check Troubleshooting section
- ποΈ Architecture: Review ARCHITECTURE.md for system details
- π¬ Discussions: GitHub Discussions
- LangChain - For the powerful agent framework
- Neo4j - For the knowledge graph database
- OpenAI - For GPT models and embeddings
- Universal Robots - For UR5 robotic arm platform
- Ultralytics - For YOLO object detection
If you find this project useful, please consider giving it a star! β
Repository: github.com/namanjain4463/Flower-Order-Assistant
Version: 1.0
Last Updated: December 6, 2025
Status: Production Ready