edit proshivka

This commit is contained in:
Dana Markova
2025-04-30 12:16:18 +03:00
parent 1f97891439
commit 27a120fc7f
12 changed files with 707 additions and 4 deletions

156
DroneClientCpp/WsServer.h Normal file
View File

@ -0,0 +1,156 @@
#pragma once
#include <Windows.h>
#using <System.dll>
#using <System.Net.Http.dll>
#pragma pack(push, 1)
struct angles_native { float pitch, roll, yaw; };
#pragma pack(pop)
using namespace System;
using namespace System::Collections::Generic;
using namespace System::Net;
using namespace System::Net::WebSockets;
using namespace System::Threading;
using namespace System::Text;
using namespace DroneClient; // ← поправьте, если у вас другое
public ref class WsServer // имя можно оставить тем же
{
public:
WsServer() : _connected(false) {}
/* ---------- подключение --------------------------------------- */
bool Connect(String^ uri)
{
if (_connected) return true; // уже подключены
_ws = gcnew ClientWebSocket();
_cts = gcnew CancellationTokenSource();
try
{
// 1) запускаем асинхронное соединение
System::Threading::Tasks::Task^ t =
_ws->ConnectAsync(gcnew Uri(uri), _cts->Token);
// 2) ждём завершения
t->Wait(); // здесь AggregateException «обёртывает»
// все реальные ошибки
_connected = true;
}
catch (AggregateException^ ag)
{
// сообщений может быть несколько выводим главное
Exception^ ex = ag->InnerExceptions->Count
? ag->InnerExceptions[0] : ag;
System::String^ msg = ex->Message;
// типовые причины:
// • WebSocketException (ошибка DNS / connection refused / timeout)
// • NotSupportedException (Windows 7: платформа без WebSocketклиента)
// • InvalidOperationException (неверный URI)
// → выводим в Debug и просто возвращаем false
System::Diagnostics::Debug::WriteLine("Connect error: " + msg);
_connected = false;
}
catch (Exception^ ex) // на всякий случай «прочие»
{
System::Diagnostics::Debug::WriteLine("Connect error: " + ex->Message);
_connected = false;
}
return _connected;
}
/* ---------- отключение ---------------------------------------- */
void Disconnect()
{
if (!_connected) return;
try
{
_ws->CloseAsync(WebSocketCloseStatus::NormalClosure,
"bye", CancellationToken::None)->Wait();
}
catch (Exception^) { /* игнор */ }
_ws = nullptr;
_cts = nullptr;
_connected = false;
}
/* ---------- быстрая отправка строки --------------------------- */
bool SendString(String^ msg)
{
if (!_connected) return false;
array<Byte>^ bytes = Encoding::UTF8->GetBytes(msg);
try
{
_ws->SendAsync(ArraySegment<Byte>(bytes),
WebSocketMessageType::Text,
true, CancellationToken::None)->Wait();
return true;
}
catch (Exception^) { return false; }
}
/* ---------- состояние ---------------------------------------- */
property bool IsConnected
{
bool get() { return _connected; }
}
void SendAnglesBinary(float p, float r, float y)
{
angles_native a = { p, r, y };
// безопасно копируем struct → byte[]
array<System::Byte>^ buf = gcnew array<System::Byte>(sizeof(a));
System::Runtime::InteropServices::GCHandle h =
System::Runtime::InteropServices::GCHandle::Alloc(buf,
System::Runtime::InteropServices::GCHandleType::Pinned);
memcpy(h.AddrOfPinnedObject().ToPointer(), &a, sizeof(a));
h.Free();
// шлём как Binary
_ws->SendAsync(System::ArraySegment<Byte>(buf),
System::Net::WebSockets::WebSocketMessageType::Binary,
true, System::Threading::CancellationToken::None)->Wait();
}
void TxLoop(System::Object^ param)
{
Drone^ d = safe_cast<Drone^>(param);
// 20 мс = 50 Гц
const int PERIOD_MS = 20;
// примерные значения, чтобы «шевелились»
float pitch = 0.0f, roll = 0.0f, yaw = 0.0f;
while (_runTx && _connected)
{
float p = System::Threading::Volatile::Read(d->pitch);
float r = System::Threading::Volatile::Read(d->roll);
float y = System::Threading::Volatile::Read(d->yaw);
SendAnglesBinary(p,r, y);
System::Threading::Thread::Sleep(PERIOD_MS);
}
}
private:
ClientWebSocket^ _ws;
CancellationTokenSource^ _cts;
bool _connected;
public:
// --- рядом с тем, где уже лежит wsClient ---
System::Threading::Thread^ _txThread = nullptr; // поток передатчик
bool _runTx = false; // признак «живого» цикла
};