Skip to content
Closed
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
5d69fce
Basic openwakeword demo
jakethesnake420 Jan 15, 2024
74d09de
removed pyaudio and update README
jakethesnake420 Jan 15, 2024
c9cdba2
microphone subscriber stream
jakethesnake420 Jan 16, 2024
e6dc6f7
bump cereal
jakethesnake420 Jan 16, 2024
248fe17
cleanup
jakethesnake420 Jan 16, 2024
b4980a6
switch to new microphone service
jakethesnake420 Jan 17, 2024
7a95204
bump cereal
jakethesnake420 Jan 17, 2024
f619eb7
micd: Send microphoneRaw and don't enforce rate with rate keeper
jakethesnake420 Jan 17, 2024
4677b04
bump cereal
jakethesnake420 Jan 17, 2024
105aedb
use 16bit audio
jakethesnake420 Jan 17, 2024
7854f96
Track skipped samples
jakethesnake420 Jan 17, 2024
6bcc4cc
run until closed
jakethesnake420 Jan 17, 2024
87a2891
run until closed
jakethesnake420 Jan 17, 2024
5d1c47d
bump cereal
jakethesnake420 Jan 17, 2024
a3c28fc
Wait for sounddevice to start before rate keeper starts
jakethesnake420 Jan 17, 2024
415d27c
Buffer samples in queue for slow connections and publish responses to…
jakethesnake420 Jan 17, 2024
6338af3
fix typo
jakethesnake420 Jan 17, 2024
fa04d3d
better timeouts for google speech api
jakethesnake420 Jan 17, 2024
70605c5
update poetry
jakethesnake420 Jan 17, 2024
0ab436c
update speech_printer.py
jakethesnake420 Jan 17, 2024
95373f9
speechToText UI label widget
jakethesnake420 Jan 17, 2024
f2c07dc
micd don't use ratekeeper
jakethesnake420 Jan 17, 2024
606fff2
remove whitespace
jakethesnake420 Jan 17, 2024
23e500b
delete my_micd
jakethesnake420 Jan 17, 2024
fa3aa0b
delete stand_alones
jakethesnake420 Jan 17, 2024
c07ce00
poetry set google clound speech version
jakethesnake420 Jan 17, 2024
acdb3af
use rev.ai instead of google
jakethesnake420 Jan 18, 2024
43e763d
update ui assistant logig
jakethesnake420 Jan 18, 2024
5174581
bump cereal
jakethesnake420 Jan 18, 2024
f739b11
fix imports
jakethesnake420 Jan 18, 2024
18dcfed
assert Model __init__.py
jakethesnake420 Jan 18, 2024
d0b875a
speech_printer.py update
jakethesnake420 Jan 18, 2024
f0d7c6f
fix messaging init
jakethesnake420 Jan 18, 2024
4884cf8
update README.md
jakethesnake420 Jan 18, 2024
f48cfbe
Delete google speech spyware
jakethesnake420 Jan 18, 2024
edfa000
replace google speech with rev.ai in .toml
jakethesnake420 Jan 18, 2024
c8aeda3
init final transcript
jakethesnake420 Jan 18, 2024
c90fc4f
added wakewordd unit test without sound files
jakethesnake420 Jan 19, 2024
11ad162
fix tab size
jakethesnake420 Jan 19, 2024
6f2e24c
oops
jakethesnake420 Jan 19, 2024
523080f
more modular
jakethesnake420 Jan 19, 2024
0d36434
keep the assistantOverlay raised
jakethesnake420 Jan 19, 2024
60cb674
**hopefully** make the assistant overlay less buggy
jakethesnake420 Jan 19, 2024
b7dcf8d
Added wakeword unittest
jakethesnake420 Jan 19, 2024
9d5e429
bump cereal
jakethesnake420 Jan 19, 2024
33bde7d
oops
jakethesnake420 Jan 19, 2024
60d7e69
do it like this
jakethesnake420 Jan 19, 2024
2841aff
I think this is good enough
jakethesnake420 Jan 19, 2024
0a60f5f
set .gitmodules
jnewb1 Jan 19, 2024
7be0f17
Merge remote-tracking branch 'origin/master' into wake-word-demo
jnewb1 Jan 19, 2024
04c571c
bump
jnewb1 Jan 19, 2024
fa7c4bc
bump
jnewb1 Jan 19, 2024
b651db3
Only run onroad
jakethesnake420 Jan 20, 2024
2d2dc83
Only run onroad unless PC
jakethesnake420 Jan 20, 2024
7dfe752
widget state refactor. Hopefully less buggy
jakethesnake420 Jan 20, 2024
207123b
bump cereal
jakethesnake420 Jan 20, 2024
b9f64a5
don't print so much
jakethesnake420 Jan 20, 2024
e809f8e
cleanup
jakethesnake420 Jan 20, 2024
52a3daa
cleanup added nav setter
jakethesnake420 Jan 21, 2024
6d2d7f2
nav setter and cleanup
jakethesnake420 Jan 21, 2024
9c045db
less lines. remove comments
jakethesnake420 Jan 21, 2024
1d12867
less lines
jakethesnake420 Jan 21, 2024
a967a15
cleaning
jakethesnake420 Jan 21, 2024
abbafb6
fix static analysis
jakethesnake420 Jan 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
url = ../../commaai/opendbc.git
[submodule "cereal"]
path = cereal
url = ../../commaai/cereal.git
url = ../../jakethesnake420/cereal.git
[submodule "rednose_repo"]
path = rednose_repo
url = ../../commaai/rednose.git
Expand Down
2 changes: 1 addition & 1 deletion cereal
2 changes: 2 additions & 0 deletions common/params.cc
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"RecordFrontLock", PERSISTENT}, // for the internal fleet
{"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"SpeechToTextAllowed", PERSISTENT},
{"SshEnabled", PERSISTENT},
{"TermsVersion", PERSISTENT},
{"Timezone", PERSISTENT},
Expand All @@ -205,6 +206,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"UpdaterLastFetchTime", PERSISTENT},
{"Version", PERSISTENT},
{"VisionRadarToggle", PERSISTENT},
{"WakeWordDetected", CLEAR_ON_MANAGER_START},
{"WheeledBody", PERSISTENT},
};

Expand Down
36 changes: 27 additions & 9 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ sounddevice = "*"
spidev = { version = "*", platform = "linux" }
sympy = "*"
websocket_client = "*"
rev_ai = { git = "https://github.com/jakethesnake420/revai-python-sdk.git", branch = "patch-1" }

# these should be removed
markdown-it-py = "*"
Expand Down
4 changes: 3 additions & 1 deletion selfdrive/manager/process_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def only_offroad(started, params, CP: car.CarParams) -> bool:
NativeProcess("logcatd", "system/logcatd", ["./logcatd"], only_onroad),
NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad),
PythonProcess("logmessaged", "system.logmessaged", always_run),
PythonProcess("micd", "system.micd", iscar),
PythonProcess("micd", "system.micd", always_run),
PythonProcess("timezoned", "system.timezoned", always_run, enabled=not PC),

PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(not PC or WEBCAM)),
Expand Down Expand Up @@ -81,6 +81,8 @@ def only_offroad(started, params, CP: car.CarParams) -> bool:
PythonProcess("updated", "selfdrive.updated", only_offroad, enabled=not PC),
PythonProcess("uploader", "system.loggerd.uploader", always_run),
PythonProcess("statsd", "selfdrive.statsd", always_run),
PythonProcess("speechd", "system.assistant.rev_speechd", always_run),
PythonProcess("wakewordd", "system.assistant.wakewordd", always_run),

# debug procs
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar),
Expand Down
2 changes: 1 addition & 1 deletion selfdrive/ui/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.cc",
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc",
"qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc"]
"qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc", "qt/widgets/assistant.cc"]

qt_env['CPPDEFINES'] = []
if maps:
Expand Down
1 change: 1 addition & 0 deletions selfdrive/ui/qt/home.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void HomeWindow::updateState(const UIState &s) {
body->setEnabled(true);
slayout->setCurrentWidget(body);
}
emit requestRaiseAssistantOverlay();
}

void HomeWindow::offroadTransition(bool offroad) {
Expand Down
1 change: 1 addition & 0 deletions selfdrive/ui/qt/home.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class HomeWindow : public QWidget {
signals:
void openSettings(int index = 0, const QString &param = "");
void closeSettings();
void requestRaiseAssistantOverlay();

public slots:
void offroadTransition(bool offroad);
Expand Down
94 changes: 94 additions & 0 deletions selfdrive/ui/qt/widgets/assistant.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "assistant.h"

AssistantOverlay::AssistantOverlay(QWidget *parent) : QLabel(parent) {

setStyleSheet("QLabel {"
" background-color: #373737;"
" border-radius: 20px;"
" font-family: 'Inter';"
" font-size: 60px;"
" color: white;" // Text color
"}");

// Set up the animations
showAnimation = new QPropertyAnimation(this, "geometry");
showAnimation->setDuration(250); // Duration in milliseconds

hideAnimation = new QPropertyAnimation(this, "geometry");
hideAnimation->setDuration(250);

int height = 100; // Fixed height
setGeometry(0, 0, 0, height);

hideTimer = new QTimer(this);
connect(hideTimer, &QTimer::timeout, this, &AssistantOverlay::animateHide);

QObject::connect(uiState(), &UIState::uiUpdate, this, &AssistantOverlay::updateState);
hide();
}

void AssistantOverlay::animateShow() {
parentCenterX = parentWidget()->width() / 2;
finalWidth = parentWidget()->width() * 0.5;
startX = parentCenterX - finalWidth / 2;
QRect startRect(parentCenterX, 0, 0, height()); // Centered, zero width
QRect endRect(startX, 0, finalWidth, height()); // Adjusted x, final width
showAnimation->setStartValue(startRect);
showAnimation->setEndValue(endRect);
show();
showAnimation->start();
}

void AssistantOverlay::animateHide() {
parentCenterX = parentWidget()->width() / 2;
finalWidth = parentWidget()->width() * 0.5;
startX = parentCenterX - finalWidth / 2;
QRect startRect(startX, 0, finalWidth, height()); // Adjusted x, final width
QRect endRect(parentCenterX, 0, 0, height()); // Centered, zero width
hideAnimation->setStartValue(startRect);
hideAnimation->setEndValue(endRect);
hideAnimation->start();
hideTimer->stop();
}

void AssistantOverlay::updateText(QString text) {
this->setText(text);
this->setAlignment(QFontMetrics(this->font()).horizontalAdvance(text) > this->finalWidth ? Qt::AlignRight : Qt::AlignCenter);
}

void AssistantOverlay::updateState(const UIState &s) {
const SubMaster &sm = *(s.sm);
static bool show_allowed = false;
static bool visable = false;
if (!sm.updated("speechToText")) {
return; // Early exit if speechToText is not updated
}
// Should probably refactor to a switch statement but its working.
if (cereal::SpeechToText::State::BEGIN == sm["speechToText"].getSpeechToText().getState()) {
show_allowed = true;
this->animateShow();
updateText("Hello, I'm listening");
if (hideTimer->isActive()) {
hideTimer->stop();
}
visable = true; // Require begin state or not valid to show
} else if (!sm["speechToText"].getValid()){ // show if not valid and show set the error text, then lock out and hide until next begin
if (!visable && show_allowed) {this->animateShow(); visable = true;}
updateText("Sorry, an error occorred");
hideTimer->start(8000);
show_allowed = false;
} else if (cereal::SpeechToText::State::EMPTY == sm["speechToText"].getSpeechToText().getState()){
updateText("Sorry, I didn't catch that");
hideTimer->start(8000);
visable = false;
show_allowed = false;
} else if (show_allowed){ // Interim and Final Results
updateText(QString::fromStdString(sm["speechToText"].getSpeechToText().getResult()));
if (sm["speechToText"].getSpeechToText().getFinalResultReady()) {
hideTimer->start(8000);
visable = false;
}
} else { //shouldn't get here unless I missed something
qWarning() << "AssistantOverlay in bad state";
}
}
28 changes: 28 additions & 0 deletions selfdrive/ui/qt/widgets/assistant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "selfdrive/ui/ui.h"
#include <QLabel>
#include <QPropertyAnimation>

class AssistantOverlay : public QLabel {
Q_OBJECT

public:
explicit AssistantOverlay(QWidget *parent = nullptr);
void animateShow();
void animateHide();

private:
void updateText(const QString text);
void startHideTimer();
QTimer *hideTimer;
QPropertyAnimation *showAnimation;
QPropertyAnimation *hideAnimation;
int parentCenterX;
int finalWidth;
int startX;

private slots:
void updateState(const UIState &s);

};
7 changes: 7 additions & 0 deletions selfdrive/ui/qt/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
main_layout = new QStackedLayout(this);
main_layout->setMargin(0);

assistantOverlay = new AssistantOverlay(this);
homeWindow = new HomeWindow(this);
main_layout->addWidget(homeWindow);
QObject::connect(homeWindow, &HomeWindow::openSettings, this, &MainWindow::openSettings);
QObject::connect(homeWindow, &HomeWindow::closeSettings, this, &MainWindow::closeSettings);
QObject::connect(homeWindow, &HomeWindow::requestRaiseAssistantOverlay, this, &MainWindow::raiseAssistantOverlay);

settingsWindow = new SettingsWindow(this);
main_layout->addWidget(settingsWindow);
Expand All @@ -33,15 +35,18 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
main_layout->setCurrentWidget(onboardingWindow);
}


Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) {
if (!offroad) {
closeSettings();
}
assistantOverlay->raise();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure all these raises are required

});
QObject::connect(device(), &Device::interactiveTimeout, [=]() {
if (main_layout->currentWidget() == settingsWindow) {
closeSettings();
}
assistantOverlay->raise();
});

// load fonts
Expand All @@ -68,6 +73,7 @@ MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
void MainWindow::openSettings(int index, const QString &param) {
main_layout->setCurrentWidget(settingsWindow);
settingsWindow->setCurrentPanel(index, param);
assistantOverlay->raise();
}

void MainWindow::closeSettings() {
Expand All @@ -80,6 +86,7 @@ void MainWindow::closeSettings() {
homeWindow->showMapPanel(true);
}
}
assistantOverlay->raise();
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
Expand Down
5 changes: 4 additions & 1 deletion selfdrive/ui/qt/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@
#include "selfdrive/ui/qt/home.h"
#include "selfdrive/ui/qt/offroad/onboarding.h"
#include "selfdrive/ui/qt/offroad/settings.h"
#include "selfdrive/ui/qt/widgets/assistant.h"

class MainWindow : public QWidget {
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

white space

private:
bool eventFilter(QObject *obj, QEvent *event) override;
void openSettings(int index = 0, const QString &param = "");
void closeSettings();
void raiseAssistantOverlay() {assistantOverlay->raise();};

QStackedLayout *main_layout;
HomeWindow *homeWindow;
SettingsWindow *settingsWindow;
OnboardingWindow *onboardingWindow;
AssistantOverlay *assistantOverlay;
};
2 changes: 1 addition & 1 deletion selfdrive/ui/ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ UIState::UIState(QObject *parent) : QObject(parent) {
sm = std::make_unique<SubMaster, const std::initializer_list<const char *>>({
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
"pandaStates", "carParams", "driverMonitoringState", "carState", "liveLocationKalman", "driverStateV2",
"wideRoadCameraState", "managerState", "navInstruction", "navRoute", "uiPlan",
"wideRoadCameraState", "managerState", "navInstruction", "navRoute", "uiPlan", "speechToText",
});

Params params;
Expand Down
19 changes: 19 additions & 0 deletions system/assistant/openwakeword/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
The openwakeword driectory code was copied from https://github.com/dscripka/openWakeWord
and then stripped down to the essentials for Openpilot's purposes.

To test wake word detection on the comma device or PC, run wakeword.py and say "alexa".
Make sure you have onnxruntime==1.16.3 when running on the comma device.

pip install onnxruntime==1.16.3

You can also run rev_speechd.py which will wait for the "WakeWordDetected" param to be set.
To setup the Rev.Ai api you need to install rev_ai:

pip install rev_ai
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my PR for rev_ai revdotcom/revai-python-sdk#111


You also need to set your rev ai acccess token which can be obtained with a free account. https://www.rev.ai/access-token
Once you have your token you can paste it in launch_openpilot.sh.

export REVAI_ACCESS_TOKEN=""

Once you have everything set up you can run ./launch_openpilot and see the assistant overlay on the UI. You can also run ./ui, rev_speechd.py, wakeword.py, micd.py in their own terminals for testing.
Loading