Skip to content

Commit 574555b

Browse files
committed
Require frontend to continually acknowledge SPARK MAX heartbeat
1 parent f06b3d3 commit 574555b

File tree

8 files changed

+57
-6
lines changed

8 files changed

+57
-6
lines changed

dist/binding.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ export declare const readHALStreamSession: (streamHandle: number, numMessages: n
4444
export declare const closeHALStreamSession: (streamHandle: number) => void;
4545
export declare const setThreadPriority: (descriptor: string, priority: ThreadPriority) => void;
4646
export declare const setSparkMaxHeartbeatData: (descriptor: string, heartbeatData: number[]) => void;
47+
export declare const ackSparkMaxHeartbeat: () => void;

dist/binding.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
3-
exports.setSparkMaxHeartbeatData = exports.setThreadPriority = exports.closeHALStreamSession = exports.readHALStreamSession = exports.openHALStreamSession = exports.writeDfuToBin = exports.stopNotifier = exports.waitForNotifierAlarm = exports.intializeNotifier = exports.sendHALMessage = exports.sendCANMessage = exports.getCANDetailStatus = exports.closeStreamSession = exports.readStreamSession = exports.openStreamSession = exports.receiveMessage = exports.unregisterDeviceFromHAL = exports.registerDeviceToHAL = exports.getDevices = exports.ThreadPriority = void 0;
3+
exports.ackSparkMaxHeartbeat = exports.setSparkMaxHeartbeatData = exports.setThreadPriority = exports.closeHALStreamSession = exports.readHALStreamSession = exports.openHALStreamSession = exports.writeDfuToBin = exports.stopNotifier = exports.waitForNotifierAlarm = exports.intializeNotifier = exports.sendHALMessage = exports.sendCANMessage = exports.getCANDetailStatus = exports.closeStreamSession = exports.readStreamSession = exports.openStreamSession = exports.receiveMessage = exports.unregisterDeviceFromHAL = exports.registerDeviceToHAL = exports.getDevices = exports.ThreadPriority = void 0;
44
var util_1 = require("util");
55
var addon = require('bindings')('addon');
66
var ThreadPriority;
@@ -32,3 +32,4 @@ exports.readHALStreamSession = addon.readHALStreamSession;
3232
exports.closeHALStreamSession = addon.closeHALStreamSession;
3333
exports.setThreadPriority = addon.setThreadPriority;
3434
exports.setSparkMaxHeartbeatData = addon.setSparkMaxHeartbeatData;
35+
exports.ackSparkMaxHeartbeat = addon.ackSparkMaxHeartbeat;

lib/binding.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ export const openHALStreamSession: (messageId: number, messageMask:number, numMe
5353
export const readHALStreamSession: (streamHandle:number, numMessages:number) => CanMessage[] = addon.readHALStreamSession;
5454
export const closeHALStreamSession: (streamHandle:number) => void = addon.closeHALStreamSession;
5555
export const setThreadPriority: (descriptor: string, priority: ThreadPriority) => void = addon.setThreadPriority;
56-
export const setSparkMaxHeartbeatData: (descriptor: string, heartbeatData: number[]) => void = addon.setSparkMaxHeartbeatData;
56+
export const setSparkMaxHeartbeatData: (descriptor: string, heartbeatData: number[]) => void = addon.setSparkMaxHeartbeatData;
57+
export const ackSparkMaxHeartbeat: () => void = addon.ackSparkMaxHeartbeat;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-can-bridge",
3-
"version": "1.0.9",
3+
"version": "1.0.10",
44
"author": "REV Robotics",
55
"description": "Get CAN Data",
66
"license": "MIT",

src/addon.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
4040
Napi::Function::New(env, setThreadPriority));
4141
exports.Set(Napi::String::New(env, "setSparkMaxHeartbeatData"),
4242
Napi::Function::New(env, setSparkMaxHeartbeatData));
43+
exports.Set(Napi::String::New(env, "ackSparkMaxHeartbeat"),
44+
Napi::Function::New(env, ackSparkMaxHeartbeat));
4345
return exports;
4446
}
4547

src/canWrapper.cc

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <set>
1717
#include <exception>
1818
#include <mutex>
19+
#include <ctime>
1920
#include "canWrapper.h"
2021
#include "DfuSeFile.h"
2122

@@ -25,6 +26,8 @@ rev::usb::CandleWinUSBDriver* driver = new rev::usb::CandleWinUSBDriver();
2526
std::map<std::string, std::shared_ptr<rev::usb::CANDevice>> CANDeviceMap;
2627
std::set<std::string> devicesRegisteredToHal;
2728
bool halInitialized = false;
29+
std::vector<std::string> heartbeatsRunning;
30+
auto latestHeartbeatAck = std::chrono::system_clock::now();
2831
uint32_t m_notifier;
2932

3033
void removeExtraDevicesFromDeviceMap(std::vector<std::string> descriptors) {
@@ -588,6 +591,25 @@ void writeDfuToBin(const Napi::CallbackInfo& info) {
588591
cb.Call(info.Env().Global(), {info.Env().Null(), Napi::Number::New(info.Env(), status)});
589592
}
590593

594+
void heartbeatWatchdog() {
595+
while(heartbeatsRunning.size() > 0) {
596+
std::this_thread::sleep_for (std::chrono::seconds(1));
597+
auto now = std::chrono::system_clock::now();
598+
std::chrono::duration<double> elapsed_seconds = now-latestHeartbeatAck;
599+
if (elapsed_seconds.count() > 1) {
600+
uint8_t heartbeat[] = {0, 0, 0, 0, 0, 0, 0, 0};
601+
for(int i = 0; i < heartbeatsRunning.size(); i++) {
602+
_sendCANMessage(heartbeatsRunning[i], 0x2052C80, heartbeat, 8, -1);
603+
}
604+
heartbeatsRunning.clear();
605+
}
606+
}
607+
}
608+
609+
void ackSparkMaxHeartbeat(const Napi::CallbackInfo& info) {
610+
latestHeartbeatAck = std::chrono::system_clock::now();
611+
}
612+
591613
// Params:
592614
// descriptor: string
593615
// heartbeatData: Number[]
@@ -608,6 +630,27 @@ void setSparkMaxHeartbeatData(const Napi::CallbackInfo& info) {
608630
sum+= heartbeat[i];
609631
}
610632

611-
if (sum == 0) _sendCANMessage(descriptor, 0x2052C80, heartbeat, 8, -1);
612-
else _sendCANMessage(descriptor, 0x2052C80, heartbeat, 8, 1);
633+
if (sum == 0) {
634+
_sendCANMessage(descriptor, 0x2052C80, heartbeat, 8, -1);
635+
for(int i = 0; i < heartbeatsRunning.size(); i++) {
636+
if (heartbeatsRunning[i].compare(descriptor) == 0) {
637+
heartbeatsRunning.erase(heartbeatsRunning.begin() + i);
638+
return;
639+
}
640+
}
641+
}
642+
else {
643+
_sendCANMessage(descriptor, 0x2052C80, heartbeat, 8, 1);
644+
if (heartbeatsRunning.size() == 0) {
645+
heartbeatsRunning.push_back(descriptor);
646+
latestHeartbeatAck = std::chrono::system_clock::now();
647+
std::thread hb(heartbeatWatchdog);
648+
hb.detach();
649+
} else {
650+
for(int i = 0; i < heartbeatsRunning.size(); i++) {
651+
if (heartbeatsRunning[i].compare(descriptor) == 0) return;
652+
}
653+
heartbeatsRunning.push_back(descriptor);
654+
}
655+
}
613656
}

src/canWrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ Napi::Array readHALStreamSession(const Napi::CallbackInfo& info);
2323
void closeHALStreamSession(const Napi::CallbackInfo& info);
2424
void setThreadPriority(const Napi::CallbackInfo& info);
2525
void setSparkMaxHeartbeatData(const Napi::CallbackInfo& info);
26+
void ackSparkMaxHeartbeat(const Napi::CallbackInfo& info);
2627
#endif

test/test_binding.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ async function testHeartbeat() {
213213
if (devices.length === 0) return;
214214
await addon.sendCANMessage(devices[0].descriptor, 33882241, [10, 215, 163, 60, 0, 0, 0, 0], 0);
215215
await addon.setSparkMaxHeartbeatData(devices[0].descriptor, Array(8).fill(0xFF));
216-
await new Promise(resolve => {setTimeout(resolve, 2000)});
216+
const interval = setInterval(addon.ackSparkMaxHeartbeat, 900);
217+
await new Promise(resolve => {setTimeout(resolve, 6000)});
218+
clearInterval(interval);
217219
console.log("STOPPING");
218220
await addon.setSparkMaxHeartbeatData(devices[0].descriptor, Array(8).fill(0x00));
219221
await new Promise(resolve => {setTimeout(resolve, 2000)});

0 commit comments

Comments
 (0)