15 #include <sys/types.h>
21 #include <visiontransfer/internal/internalinformation.h>
22 #include <visiontransfer/internal/networking.h>
23 #include <visiontransfer/internal/datachannelservicebase.h>
24 #include <visiontransfer/internal/datachannel-control.h>
25 #include <visiontransfer/datachannelservice.h>
27 #include <visiontransfer/internal/datachannel-imu-bno080.h>
28 #include <visiontransfer/internal/protocol-sh2-imu-bno080.h>
42 using namespace visiontransfer;
43 using namespace visiontransfer::internal;
45 namespace visiontransfer {
50 sockaddr_in serverAddr;
52 std::shared_ptr<std::thread> receiverThread;
53 unsigned long pollDelay;
55 std::shared_ptr<ClientSideDataChannelIMUBNO080> channelBNO080;
58 void initiateHandshake();
60 void unsubscribeAll();
61 void receiverRoutine();
64 std::vector<DataChannelInfo> channelsAvailable;
65 std::map<DataChannel::Type, std::set<DataChannel::ID>> channelsAvailableByType;
70 void launch(
unsigned long pollDelayUSec);
74 return channelBNO080->lastRotationQuaternion;
76 std::vector<TimestampedQuaternion> getRotationQuaternionSeries(
int fromSec,
int fromUSec,
int untilSec,
int untilUSec) {
77 return channelBNO080->ringbufRotationQuaternion.popBetweenTimes(fromSec, fromUSec, untilSec, untilUSec);
81 return channelBNO080->lastXYZ[idx - 1];
83 std::vector<TimestampedVector> getSensorVectorSeries(
int idx,
int fromSec,
int fromUSec,
int untilSec,
int untilUSec) {
84 return channelBNO080->ringbufXYZ[idx - 1].popBetweenTimes(fromSec, fromUSec, untilSec, untilUSec);
88 return channelBNO080->lastScalar[idx - 0x0a];
90 std::vector<TimestampedScalar> getSensorScalarSeries(
int idx,
int fromSec,
int fromUSec,
int untilSec,
int untilUSec) {
91 return channelBNO080->ringbufScalar[idx - 0x0a].popBetweenTimes(fromSec, fromUSec, untilSec, untilUSec);
97 class DataChannelService::Pimpl {
99 std::shared_ptr<internal::DataChannelServiceImpl> impl;
101 impl = std::make_shared<internal::DataChannelServiceImpl>(deviceInfo);
103 Pimpl(
const char* ipAddress) {
104 impl = std::make_shared<internal::DataChannelServiceImpl>(ipAddress);
108 void internal::DataChannelServiceImpl::receiverRoutine() {
109 threadRunning =
true;
110 while (threadRunning) {
112 std::this_thread::sleep_for(std::chrono::microseconds(pollDelay));
116 void internal::DataChannelServiceImpl::launch(
unsigned long pollDelayUSec) {
118 channelBNO080 = std::make_shared<ClientSideDataChannelIMUBNO080>();
119 registerChannel(channelBNO080);
121 pollDelay = pollDelayUSec;
122 receiverThread = std::make_shared<std::thread>(std::bind(&internal::DataChannelServiceImpl::receiverRoutine,
this));
123 receiverThread->detach();
129 void internal::DataChannelServiceImpl::initiateHandshake() {
130 uint16_t cmd = htons((uint16_t) DataChannelControlCommands::CTLRequestAdvertisement);
131 sendDataIsolatedPacket((DataChannel::ID) 0x00, DataChannel::Types::CONTROL, (
unsigned char*) &cmd,
sizeof(cmd), &serverAddr);
134 void internal::DataChannelServiceImpl::subscribeAll() {
135 unsigned char data[1024];
136 int len = DataChannelControlUtil::packSubscriptionMessage(data, 1024, DataChannelControlCommands::CTLRequestSubscriptions, {0});
137 sendDataIsolatedPacket((DataChannel::ID) 0x00, DataChannel::Types::CONTROL, data, len, &serverAddr);
140 void internal::DataChannelServiceImpl::unsubscribeAll() {
141 unsigned char data[1024];
142 int len = DataChannelControlUtil::packSubscriptionMessage(data, 1024, DataChannelControlCommands::CTLRequestUnsubscriptions, {0});
143 sendDataIsolatedPacket((DataChannel::ID) 0x00, DataChannel::Types::CONTROL, data, len, &serverAddr);
146 int internal::DataChannelServiceImpl::handleChannel0Message(
DataChannelMessage& message, sockaddr_in* sender) {
147 auto cmd = DataChannelControlUtil::getCommand(message.payload, message.header.payloadSize);
149 case DataChannelControlCommands::CTLProvideAdvertisement: {
151 channelsAvailable = DataChannelControlUtil::unpackAdvertisementMessage(message.payload, message.header.payloadSize);
152 for (
auto& dci: channelsAvailable) {
153 channelsAvailableByType[dci.getChannelType()].insert(dci.getChannelID());
159 case DataChannelControlCommands::CTLProvideSubscriptions: {
169 internal::DataChannelServiceImpl::DataChannelServiceImpl(
DeviceInfo deviceInfo)
173 internal::DataChannelServiceImpl::DataChannelServiceImpl(
const char* ipAddress)
175 serverAddr.sin_family = AF_INET;
176 serverAddr.sin_port = htons(InternalInformation::DATACHANNELSERVICE_PORT);
177 auto result = inet_addr(ipAddress);
178 if (result == INADDR_NONE) {
179 throw std::runtime_error(
"Failed to set address for DataChannelService");
181 serverAddr.sin_addr.s_addr = result;
190 pimpl =
new DataChannelService::Pimpl(deviceInfo);
191 pimpl->impl->launch(pollDelayUSec);
195 pimpl =
new DataChannelService::Pimpl(ipAddress);
196 pimpl->impl->launch(pollDelayUSec);
200 DataChannelService::~DataChannelService() {
201 pimpl->impl->threadRunning =
false;
206 return pimpl->impl->channelsAvailableByType.count(DataChannel::Types::BNO080);
214 return pimpl->impl->getLastRotationQuaternion();
217 return pimpl->impl->getRotationQuaternionSeries(fromSec, fromUSec, untilSec, untilUSec);
221 return pimpl->impl->getLastSensorVector(SH2Constants::SENSOR_ACCELEROMETER);
224 return pimpl->impl->getSensorVectorSeries(SH2Constants::SENSOR_ACCELEROMETER, fromSec, fromUSec, untilSec, untilUSec);
228 return pimpl->impl->getLastSensorVector(SH2Constants::SENSOR_GYROSCOPE);
231 return pimpl->impl->getSensorVectorSeries(SH2Constants::SENSOR_GYROSCOPE, fromSec, fromUSec, untilSec, untilUSec);
235 return pimpl->impl->getLastSensorVector(SH2Constants::SENSOR_MAGNETOMETER);
238 return pimpl->impl->getSensorVectorSeries(SH2Constants::SENSOR_MAGNETOMETER, fromSec, fromUSec, untilSec, untilUSec);
242 return pimpl->impl->getLastSensorVector(SH2Constants::SENSOR_LINEAR_ACCELERATION);
245 return pimpl->impl->getSensorVectorSeries(SH2Constants::SENSOR_LINEAR_ACCELERATION, fromSec, fromUSec, untilSec, untilUSec);
249 return pimpl->impl->getLastSensorVector(SH2Constants::SENSOR_GRAVITY);
252 return pimpl->impl->getSensorVectorSeries(SH2Constants::SENSOR_GRAVITY, fromSec, fromUSec, untilSec, untilUSec);