saltylab-firmware/jetson/ros2_ws/src/saltybot_social_memory_node
sl-webui 7cad97d0db
Some checks failed
social-bot integration tests / Lint (flake8 + pep257) (pull_request) Failing after 29s
social-bot integration tests / Core integration tests (mock sensors, no GPU) (pull_request) Has been skipped
social-bot integration tests / Latency profiling (GPU, Orin) (pull_request) Has been cancelled
feat: Add Issue #443 - Social memory database with persistent person knowledge
- SQLite database at /home/seb/saltybot-data/social_memory.db
- Tables: persons (name, embeddings, relationship_tier, notes), encounters (person_id, timestamp, transcript, mood)
- ROS2 services: /saltybot/social_memory/lookup, /update, /encounter, /stats
- Automatic tier promotion by encounter count (5→regular, 20→favorite)
- Quality-based promotion: 80%+ positive interactions required
- Custom greetings per relationship tier (stranger/regular/favorite)
- Encounter tracking: transcript, mood, engagement_score, positive_interaction flag
- Face embedding storage support for face recognition integration
- Relationship score computation from interaction history
- Thread-safe concurrent service calls
- Periodic stats publishing on /saltybot/social_memory/stats_update
- Backup/restore functionality with gzip compression
- Full database statistics: person counts by tier, total encounters, database size
- Configurable via social_memory.yaml: thresholds, backup dir, publish interval

Two packages:
- saltybot_social_memory: Service definitions (CMake, ROS2 services)
- saltybot_social_memory_node: Python service server with SQLite backend

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:04:49 -05:00
..

SaltyBot Social Memory Database (Issue #443)

Persistent SQLite-backed social knowledge system for maintaining person profiles, relationship history, and interaction statistics.

Features

1. Person Profile Management

  • Person Records: Name, relationship tier, custom greetings, notes, face embeddings
  • Relationship Tiers:
    • Stranger: 0 encounters (default), cold greetings
    • Regular: 5+ encounters, familiar greetings
    • Favorite: 20+ encounters (or 80%+ positive interactions), warm greetings
  • Custom Greetings: Tier-specific greeting strings
  • Face Embeddings: Optional vector storage for face recognition
  • Notes: Free-form observations about the person

2. Encounter Tracking

  • Encounter Recording:
    • Timestamp, transcript of conversation, detected mood
    • Engagement score (0.01.0)
    • Positive/negative interaction flag
  • Automatic Tier Promotion:
    • Encounter count-based: 5→regular, 20→favorite
    • Quality-based: 80%+ positive interactions required
    • Cooldown: 1 hour minimum between promotions
  • Statistics Aggregation:
    • Total encounter count per person
    • Positive interaction ratio
    • Relationship score (computed from interactions)

3. ROS2 Service Interfaces

/saltybot/social_memory/lookup

Request:
  query_type: "id" | "name" | "recent"
  query_value: person_id | name_pattern | days_back

Response:
  found: boolean
  person_id: int32
  name: string
  relationship_tier: string
  relationship_score: float32 (0.01.0)
  interaction_count: int32
  custom_greetings: string[3]  # [stranger, regular, favorite]
  notes: string
  last_seen: Time

/saltybot/social_memory/update

Request:
  person_id: int32
  name: string
  relationship_tier: string
  custom_greetings: string[3]
  notes: string
  embedding: float32[]

Response:
  success: boolean
  message: string
  updated_person_id: int32

/saltybot/social_memory/encounter

Request:
  person_id: int32
  transcript: string
  mood: string
  engagement_score: float32
  positive_interaction: boolean

Response:
  success: boolean
  message: string
  encounter_id: int32
  tier_changed_to: string (or empty if no change)

/saltybot/social_memory/stats

Request:
  (empty)

Response:
  total_persons: int32
  total_encounters: int32
  favorites_count: int32
  regulars_count: int32
  strangers_count: int32
  database_size_mb: float32
  last_backup: Time
  database_path: string

4. Statistics Publishing

  • Topic: /saltybot/social_memory/stats_update (std_msgs/String, JSON)
  • Frequency: Configurable (default 60s)
  • Content: Database statistics snapshot

5. Backup & Restore

  • Automatic Backups: Gzipped snapshots stored in backup directory
  • Backup Tracking: Recorded in database with timestamp and size
  • Manual Restore: Restore from any backup file

Database Schema

persons Table

Column Type Notes
person_id INTEGER PRIMARY KEY Auto-increment
name TEXT UNIQUE Person's name
embedding BLOB JSON-encoded face embedding
relationship_tier TEXT stranger/regular/favorite
relationship_score REAL 0.01.0 computed from encounters
interaction_count INTEGER Total encounters
positive_interactions INTEGER Count of positive encounters
greeting_stranger TEXT Greeting for strangers
greeting_regular TEXT Greeting for regular contacts
greeting_favorite TEXT Greeting for favorites
notes TEXT Custom observations
created_at TIMESTAMP When person was first recorded
last_seen TIMESTAMP Last encounter timestamp
last_tier_promotion TIMESTAMP Cooldown tracking

encounters Table

Column Type Notes
encounter_id INTEGER PRIMARY KEY Auto-increment
person_id INTEGER Foreign key to persons
transcript TEXT Conversation text/summary
detected_mood TEXT Emotion detected during encounter
engagement_score REAL 0.01.0
positive_interaction BOOLEAN Was interaction positive?
encounter_timestamp TIMESTAMP When encounter occurred

backups Table

Column Type Notes
backup_id INTEGER PRIMARY KEY Auto-increment
backup_path TEXT UNIQUE Full path to backup file
backup_timestamp TIMESTAMP When backup was created
file_size_mb REAL Compressed size in MB

Configuration

Edit config/social_memory.yaml:

database_path: "/home/seb/saltybot-data/social_memory.db"
backup_dir: "/home/seb/saltybot-data/backups"

publish_stats: true
stats_publish_interval: 60.0  # seconds

tier_promotion:
  regular_threshold: 5        # Encounters for regular tier
  favorite_threshold: 20      # Encounters for favorite tier
  positive_ratio_min: 0.8     # 80% positive required
  cooldown_hours: 1           # Minimum between promotions

Running

Launch the service node

ros2 launch saltybot_social_memory_node social_memory.launch.py

Direct execution

ros2 run saltybot_social_memory_node social_memory

Usage Examples

Add a new person

ros2 service call /saltybot/social_memory/update saltybot_social_memory/PersonUpdate \
  "{name: 'Alice', relationship_tier: 'stranger', \
    custom_greetings: ['Hello there!', 'Nice to see you!', 'Great to see you again!']}"

Record an encounter

ros2 service call /saltybot/social_memory/encounter saltybot_social_memory/EncounterRecord \
  "{person_id: 1, transcript: 'Alice: Hi! How are you?', \
    mood: 'happy', engagement_score: 0.85, positive_interaction: true}"

Lookup a person

ros2 service call /saltybot/social_memory/lookup saltybot_social_memory/PersonLookup \
  "{query_type: 'name', query_value: 'Alice'}"

Get database statistics

ros2 service call /saltybot/social_memory/stats saltybot_social_memory/DatabaseStats

Monitor statistics stream

ros2 topic echo /saltybot/social_memory/stats_update

Integration Points

  1. Emotion Engine (saltybot_emotion_engine)

    • Queries person familiarity for warmth modifier
    • Records encounters to build relationship history
  2. Person Tracker (sl-perception)

    • Provides person_id from face recognition
    • Supplies engagement_score and detected_mood
  3. Voice Recognition (sl-jetson)

    • Provides transcript of conversations
    • Records as encounter transcript
  4. Greeting System

    • Queries custom_greetings based on tier
    • Personalizes robot responses

Tier Promotion Logic

When encounter recorded:
  1. Increment interaction_count
  2. Update positive_interactions if positive_interaction=true
  3. Compute positive_ratio = positive_interactions / interaction_count
  4. Check promotion eligibility:
     - current_tier == "stranger" && interaction_count >= 5 && positive_ratio >= 0.8
       → Promote to "regular"
     - current_tier == "regular" && interaction_count >= 20 && positive_ratio >= 0.8
       → Promote to "favorite"
  5. If promoted and cooldown_hours passed since last promotion:
     - Update relationship_tier
     - Set last_tier_promotion = now()
     - Return tier_changed_to in response

Backup Strategy

  • Manual backups via backup_database() method
  • Automatic tracking in backups table with timestamp
  • Restore from any backup: restore_database(backup_path)
  • Format: gzip-compressed SQLite database (.db.gz)

Thread Safety

  • All database operations protected by threading.Lock()
  • Safe for concurrent ROS2 service calls
  • Sequential writes to ensure data integrity

Performance Characteristics

  • Lookup: O(1) indexed by person_id, O(n) by name pattern
  • Encounter recording: O(1) insertion + O(1) stats update
  • Database size: ~1KB per person + ~0.5KB per encounter

Future Enhancements

  1. Persistent memory integration with LLM (e.g., "Alice loves plants")
  2. Group relationships (track person groups/families)
  3. Preference learning (dietary restrictions, favorite topics)
  4. Sentiment analysis over time
  5. Web UI for person management
  6. Integration with voice recognition confidence
  7. Automated cleanup of old encounters (>1 year)
  8. Graph-based relationship networks