Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getLatestMessageOfEveryReceivedArbId() function #37

Merged
merged 3 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 5 additions & 22 deletions lib/binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ export class CanBridge {
startRevCommonHeartbeat: (descriptor: string) => void;
stopHeartbeats: (descriptor: string, sendDisabledHeartbeatsFirst: boolean) => void;
ackHeartbeats: () => void;
/**
* @return Object that maps arbitration IDs to the last-received message with that ID
*/
getLatestMessageOfEveryReceivedArbId: (descriptor: string, maxAgeMs: number) => Record<number, CanMessage>;

constructor() {
try {
Expand Down Expand Up @@ -103,30 +107,9 @@ export class CanBridge {
this.startRevCommonHeartbeat = addon.startRevCommonHeartbeat;
this.ackHeartbeats = addon.ackHeartbeats;
this.stopHeartbeats = addon.stopHeartbeats;
this.getLatestMessageOfEveryReceivedArbId = addon.getLatestMessageOfEveryReceivedArbId;
} catch (e: any) {
throw new CanBridgeInitializationError(e);
}
}
}






















2 changes: 1 addition & 1 deletion scripts/download-CanBridge.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from "path";
import axios from 'axios';
import AdmZip from 'adm-zip';

const canBridgeTag = "v2.5.1";
const canBridgeTag = "v2.6.0";
const canBridgeReleaseAssetUrlPrefix = `https://github.com/REVrobotics/CANBridge/releases/download/${canBridgeTag}`;

const externalCompileTimeDepsPath = 'externalCompileTimeDeps';
Expand Down
2 changes: 2 additions & 0 deletions src/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
Napi::Function::New(env, stopHeartbeats));
exports.Set(Napi::String::New(env, "ackHeartbeats"),
Napi::Function::New(env, ackHeartbeats));
exports.Set(Napi::String::New(env, "getLatestMessageOfEveryReceivedArbId"),
Napi::Function::New(env, getLatestMessageOfEveryReceivedArbId));
return exports;
}

Expand Down
54 changes: 54 additions & 0 deletions src/canWrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,60 @@ Napi::Array getImageElements(const Napi::CallbackInfo& info) {
return elements;
}

Napi::Object getLatestMessageOfEveryReceivedArbId(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
std::string descriptor = info[0].As<Napi::String>().Utf8Value();
uint32_t maxAgeMs = info[1].As<Napi::Number>().Uint32Value();

std::shared_ptr<rev::usb::CANDevice> device;

{ // This block exists to define how long we hold canDevicesMtx
std::scoped_lock lock{canDevicesMtx};
doleksy marked this conversation as resolved.
Show resolved Hide resolved
auto deviceIterator = canDeviceMap.find(descriptor);
if (deviceIterator == canDeviceMap.end()) {
if (devicesRegisteredToHal.find(descriptor) != devicesRegisteredToHal.end()) return receiveHalMessage(info);
Napi::Error::New(env, DEVICE_NOT_FOUND_ERROR).ThrowAsJavaScriptException();
return Napi::Object::New(env);
}
device = deviceIterator->second;
}

std::map<uint32_t, std::shared_ptr<rev::usb::CANMessage>> messages;
bool success = device->CopyReceivedMessagesMap(messages);
if (!success) {
Napi::Error::New(env, "Failed to copy the map of received messages").ThrowAsJavaScriptException();
return Napi::Object::New(env);
}

// TODO(Harper): Use HAL clock
const auto nowMs = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();

Napi::Object result = Napi::Object::New(env);
for (auto& m: messages) {
uint32_t arbId = m.first;
auto message = m.second;
uint32_t timestampMs = message->GetTimestampUs();

if (nowMs - timestampMs > maxAgeMs) {
continue;
}

size_t messageSize = message->GetSize();
const uint8_t* messageData = message->GetData();
Napi::Array napiMessage = Napi::Array::New(env, messageSize);
for (int i = 0; i < messageSize; i++) {
napiMessage[i] = messageData[i];
}
Napi::Object messageInfo = Napi::Object::New(env);
messageInfo.Set("messageID", message->GetMessageId());
messageInfo.Set("timeStamp", timestampMs);
messageInfo.Set("data", napiMessage);
result.Set(arbId, messageInfo);
}

return result;
}

void cleanupHeartbeatsRunning() {
// Erase removed CAN buses from heartbeatsRunning
std::scoped_lock lock{watchdogMtx, canDevicesMtx};
Expand Down
1 change: 1 addition & 0 deletions src/canWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ void setSparkMaxHeartbeatData(const Napi::CallbackInfo& info);
void startRevCommonHeartbeat(const Napi::CallbackInfo& info);
void stopHeartbeats(const Napi::CallbackInfo& info);
void ackHeartbeats(const Napi::CallbackInfo& info);
Napi::Object getLatestMessageOfEveryReceivedArbId(const Napi::CallbackInfo& info);
#endif