4 Commits
v1.0 ... master

4 changed files with 48 additions and 13 deletions

View File

@@ -2,6 +2,7 @@
Это проект с двумя частями программы: Это проект с двумя частями программы:
* программа `ground` - запускается на наземной станции * программа `ground` - запускается на наземной станции
* программа `air` - запускается на воздушной станции (SDRPi)
# Зависимости для ground # Зависимости для ground
@@ -22,3 +23,28 @@ brew install sdl2
Под шиндовс, как всегда, надо страдать. Рекомендуется установить `sdl2` через `vcpkg`. Под шиндовс, как всегда, надо страдать. Рекомендуется установить `sdl2` через `vcpkg`.
# Запуск
## на "воздушной" части:
```shell
sdrpi-fpv-control-air /dev/ttyPS0
```
> На данный момент эта команда добавлена в автозапуск, никаких дополнительных действий от пользователя не требуется.
## На "земле"
Если у вас windows, скачать релиз можно:
* с шары (`\\SHARE\share\vlad405\sdripi-fpv-control`) [(ссылка для линуксоидов)](smb://share.local/share/vlad405/sdripi-fpv-control)
* со [страницы релиза](https://git.wawaa.ru/VladislavOstapov/sdrpi-fpv-control/releases).
Если вы ~~нормальный человек~~ разработчик, то проще собрать программу при помощи cmake.
Запускать программу надо на ноуте, предварительно подключив пульт.
```shell
sdrpi-fpv-control-ground 192.168.1.5 20
```
У программы 2 необязательных аргумента. Первый - IP адрес "воздушной" SDRPi. Второй - количество пакетов управления в секунду.
По умолчанию IP адрес - localhost, а количество пакетов в секунду - 5.
Для мягкого управления рекомендуется ставить от 15 до 50 пакетов в секунду. При показе рекомендуется устанавливать значение 20.

View File

@@ -85,6 +85,8 @@ struct SbusData {
bool failsafe = false; bool failsafe = false;
bool ch17 = false, ch18 = false; bool ch17 = false, ch18 = false;
static constexpr size_t NUM_CH = 16; static constexpr size_t NUM_CH = 16;
static constexpr int16_t SBUS_CH_MIN = 173;
static constexpr int16_t SBUS_CH_MAX = 1812;
int16_t ch[NUM_CH]; int16_t ch[NUM_CH];
/* Message len */ /* Message len */
@@ -253,16 +255,24 @@ int main(int argc, char* argv[]) {
packet_count++; packet_count++;
for (int i = 0; i < data.size() && i < SbusData::NUM_CH; ++i) { for (int i = 0; i < data.size() && i < SbusData::NUM_CH; ++i) {
auto item = static_cast<int16_t>(data[i]); auto item = static_cast<double>(data[i]);
sb.ch[i] = static_cast<int16_t>((item - 1000.0) * 2); item -= 1000.0;
if (sb.ch[i] < 50) { item = std::min(item, 1000.0);
sb.ch[i] = 50; // минимальное число item = std::max(item, 0.0);
} else if (sb.ch[i] > 1900) { item *= (SbusData::SBUS_CH_MAX - SbusData::SBUS_CH_MIN) / 1000.0;
sb.ch[i] = 1900; // максимальное число item += SbusData::SBUS_CH_MIN;
sb.ch[i] = static_cast<int16_t>(item);
if (sb.ch[i] < SbusData::SBUS_CH_MIN) {
sb.ch[i] = SbusData::SBUS_CH_MIN; // минимальное число
} else if (sb.ch[i] > SbusData::SBUS_CH_MAX) {
sb.ch[i] = SbusData::SBUS_CH_MAX; // максимальное число
} }
} }
sb.fillDataBuf(); sb.fillDataBuf();
serial.write(sb.buf_); if (!serial.write(sb.buf_)) {
break;
}
// Выводим статистику каждые 100 пакетов // Выводим статистику каждые 100 пакетов
if (packet_count % 100 == 0) { if (packet_count % 100 == 0) {

View File

@@ -64,13 +64,12 @@ bool JoystickReader::readData(std::vector<uint16_t>& data) {
// Читаем кнопки // Читаем кнопки
int buttons = SDL_JoystickNumButtons(joystick); int buttons = SDL_JoystickNumButtons(joystick);
for (int i = 0; i < buttons && i < data.size() - axes; ++i) { for (int i = 0; i < buttons && i < data.size() - axes; ++i) {
auto buttonState = SDL_JoystickGetButton(joystick, i); data[axes + i] = SDL_JoystickGetButton(joystick, i) ? 2000 : 1000;
data[axes + i] = static_cast<uint16_t>(1000.0 + (buttonState * (1000.0 / 255.0)));
} }
for (auto& i: data) { for (auto& i: data) {
if (i < 950) i = 950; if (i < 1000) i = 1000;
if (i > 2050) i = 2050; if (i > 2000) i = 2000;
} }
return true; return true;
} }

View File

@@ -27,8 +27,8 @@ int main(int argc, char* argv[]) {
JoystickReader reader; JoystickReader reader;
const int64_t timeInterval = 1000 / frequency; const int64_t timeInterval = 1000 / frequency;
while (!reader.initialize()) { if (!reader.initialize()) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); return 1;
} }
UDPSocket udp(sendAddress, 1066); UDPSocket udp(sendAddress, 1066);