add r1 robot project

This commit is contained in:
Jaroslav Vizner
2026-08-28 10:10:18 +02:00
parent 27aea1146d
commit 8d88495f6f
82 changed files with 22935 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include <string>
#include "r1_voice/llm.hh"
#include "r1_voice/stt.hh"
#include "r1_voice/tts.hh"
namespace r1_voice {
struct ConversationConfig {
SttConfig stt;
LlmConfig llm;
TtsConfig tts;
};
class Conversation {
public:
explicit Conversation(
ConversationConfig config
);
bool init(
const std::string& network_interface
);
void run();
private:
ConversationConfig config_;
SpeechToText stt_;
LLM llm_;
TextToSpeech tts_;
};
} // namespace r1_voice
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include <string>
#include <vector>
namespace r1_voice {
struct ChatMessage {
std::string role;
std::string content;
};
struct LlmConfig {
std::string url =
"http://127.0.0.1:8080/v1/chat/completions";
std::string model = "local";
float temperature = 0.7f;
int max_tokens = 256;
std::string system_prompt =
"You are R1, a humanoid robot conversational assistant. "
"Talk naturally with the person in front of you. "
"Keep answers reasonably short because they will be spoken aloud. "
"Answer in the same language as the user. "
"Do not use markdown unless necessary.";
};
class LLM {
public:
explicit LLM(LlmConfig config);
std::string chat(
const std::string& user
);
private:
LlmConfig config_;
std::vector<ChatMessage> history_;
std::string escapeJson(
const std::string& text
) const;
std::string parseContent(
const std::string& json
) const;
std::string httpPost(
const std::string& body
) const;
};
} // namespace r1_voice
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#include <string>
namespace r1_voice {
struct SttConfig {
std::string whisper_cli;
std::string whisper_model;
std::string language = "cs";
int threads = 8;
static constexpr int sample_rate = 16000;
static constexpr int packet_bytes = 5120;
float speech_threshold = 0.010f;
int silence_ms = 900;
int min_speech_ms = 250;
int max_record_ms = 10000;
int preroll_ms = 800;
};
class SpeechToText {
public:
explicit SpeechToText(SttConfig config);
// Blocks until the user speaks, stops speaking,
// and Whisper has transcribed the utterance.
std::string listen();
private:
SttConfig config_;
bool recordToWav(const std::string& path);
std::string transcribe(
const std::string& wav_path
);
std::string trim(
const std::string& text
);
};
} // namespace r1_voice
+65
View File
@@ -0,0 +1,65 @@
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include <unitree/robot/r1/audio/audio_client.hpp>
namespace r1_voice {
struct TtsConfig {
std::string piper_command = "python3 -m piper";
std::string model =
"/home/jvizner/esarobotech/piper/cs_medium.onnx";
std::string output_wav =
"/tmp/r1_tts.wav";
int volume = 100;
std::string app_name = "r1_voice";
};
class TextToSpeech {
public:
explicit TextToSpeech(TtsConfig config);
bool init(
const std::string& network_interface
);
bool speak(
const std::string& text
);
private:
TtsConfig config_;
std::unique_ptr<
unitree::robot::r1::AudioClient
> client_;
bool initialized_ = false;
bool synthesize(
const std::string& text,
const std::string& wav_path
);
bool readWavPcm(
const std::string& wav_path,
std::vector<uint8_t>& pcm,
uint32_t& sample_rate,
uint16_t& channels,
uint16_t& bits_per_sample
);
bool playPcm(
const std::vector<uint8_t>& pcm
);
};
} // namespace r1_voice