Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d727f63
test
b-atteryacid May 7, 2026
9b1dee5
please
b-atteryacid May 7, 2026
6c97616
please help
b-atteryacid May 7, 2026
14255d9
gelp
b-atteryacid May 7, 2026
9fea982
sa t al rme apsk po amimr pakf peo poil
b-atteryacid May 8, 2026
d609695
alright
b-atteryacid May 9, 2026
58dcb77
no
b-atteryacid May 9, 2026
ed7cfb7
added some mercy for extra heartbeats 🫁
b-atteryacid May 9, 2026
ffe220b
added some grace and a way for daughters to exit the error state
b-atteryacid May 9, 2026
ba25344
im hungry
b-atteryacid May 9, 2026
83382d0
added heartbeat direction for better
b-atteryacid May 9, 2026
c450db3
fixed bad heartbeat receive on motherboard
b-atteryacid May 9, 2026
9d387ed
separated mother-daughter dir com can id
b-atteryacid May 9, 2026
0bf48da
daughters now make sure to exhaust the whole heartbeat queue
b-atteryacid May 9, 2026
6b5c54d
faster heartbeat checking, ack checking for other boards joining
b-atteryacid May 9, 2026
df9095d
hopefully fix daughters giving up and exploding when another board tr…
b-atteryacid May 9, 2026
8e8e933
actually make the last one build properyl
b-atteryacid May 9, 2026
1b681ff
dbg print
b-atteryacid May 9, 2026
5888831
this time for sure
b-atteryacid May 9, 2026
50e2126
Merge branch 'adamg/fix' of https://github.com/UCSOAR/CommunicationSy…
b-atteryacid May 9, 2026
66156c1
-now kicks repeat join boards for faster recovery on daughter reset
b-atteryacid May 9, 2026
1e2f593
- fixed daughter node on motherboard index setting with multiple boards
b-atteryacid May 9, 2026
58224b7
cleanup, limit defines adjustment for smaller node sizes
b-atteryacid May 12, 2026
add244a
now packs can structs to avoid compiler flags potentially causing iss…
b-atteryacid May 12, 2026
369f508
packing macros, sol logs
b-atteryacid May 15, 2026
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
25 changes: 3 additions & 22 deletions CanAutoNode/CanAutoNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include <CanAutoNode.hpp>
#include <cstring>



CanAutoNode::~CanAutoNode() {

}
Expand Down Expand Up @@ -44,9 +42,7 @@ bool CanAutoNode::IDRangesOverlap(IDRange a, IDRange b) {
* @return Node represented by the bytes.
*/
CanAutoNode::Node CanAutoNode::nodeFromMsg(const uint8_t *msg) {

return MsgToData<Node>(msg);

}

/* Converts a 32-bit integer into a byte sequence (big-endian).
Expand All @@ -62,10 +58,7 @@ void CanAutoNode::shift32to8(uint32_t in, uint8_t *out) {
* @param msgout Pointer to output buffer. Must be as long as a Node struct.
*/
void CanAutoNode::msgFromNode(Node node, uint8_t *msgout) {

memcpy(msgout,&node,sizeof(Node));


}

CanAutoNode::CanAutoNode() {
Expand All @@ -92,7 +85,6 @@ bool CanAutoNode::SendMessageToDaughterBoardByCANIDOffset(UniqueBoardID boardID,
}
}
return false;

}

/* Sends a message starting at a given CAN ID, regardless of which board has claimed it.
Expand Down Expand Up @@ -132,7 +124,6 @@ bool CanAutoNode::SendMessageToAllBoardsOfTypeByLogIndex(uint8_t boardType,
}
}
return foundOne;

}

#ifdef CANAUTONODEDEBUG
Expand All @@ -151,15 +142,12 @@ void CanAutoNode::PrintBoardID(CanAutoNode::UniqueBoardID id) {
* @return true if successfully sent.
*/
bool CanAutoNode::SendHeartbeat() {

HeartbeatInfo beat;
beat.senderBoardID = thisNode.uniqueID;

beat.dir = GetDir();
uint8_t msg[sizeof(HeartbeatInfo)] = {};
memcpy(msg,&beat,sizeof(msg));
return controller->SendByLogIndex(msg, HEARTBEAT_ID);
//return controller->SendByMsgID(msg, sizeof(msg), HEARTBEAT_ID);

return controller->SendByMsgID(msg, sizeof (msg), HEARTBEAT_CAN_ID);
}

/* Sends a message to a daughter board by a log index on that daughter board. Can be called from
Expand All @@ -177,7 +165,7 @@ bool CanAutoNode::SendMessageToDaughterByLogIndex(UniqueBoardID boardID,
for(uint16_t i = 0; i < nodesInNetwork; i++) {
const Node& thisDaughter = daughterNodes[i];
if(thisDaughter.uniqueID == boardID) {
return controller->SendByMsgID(msg, thisDaughter.logSizesInBytes[logIndex], thisDaughter.logOffsetsInCANIDs[logIndex]+thisDaughter.canIDRange.start);
return controller->SendByMsgID(msg, thisDaughter.logSizesInBytes[logIndex], thisDaughter.logOffsetsInCANIDs[logIndex]+thisDaughter.canIDRange.start+SEND_RECEIVE_ID_SPLIT_AMOUNT);
}
}
return false;
Expand Down Expand Up @@ -241,7 +229,6 @@ bool CanAutoNode::ReadMessageFromRXBuf(uint8_t logIndex, uint16_t logSize, uint8
memcpy(out,paddedOut,logSize);
return true;
}

#ifdef CANAUTONODEDEBUG
//SOAR_PRINT("Buffer large enough, attempting read...\n");
#endif
Expand All @@ -263,16 +250,13 @@ bool CanAutoNode::BoardExistsWithName(const char* name) {
uint16_t CanAutoNode::GetNamesOfAllBoards(char(* outputArr)[MAX_NAME_STR_LEN], uint16_t outputArrayLen) {
uint16_t num = 0;
strncpy(outputArr[num++],thisNode.nodeName,MAX_NAME_STR_LEN);
//
for(uint16_t i = 0; i < nodesInNetwork; i++) {
strncpy(outputArr[num++],daughterNodes[i].nodeName,MAX_NAME_STR_LEN);
if(num >= outputArrayLen) {
break;
}
}

return num;

}

uint16_t CanAutoNode::GetIDsOfAllBoards(CanAutoNode::UniqueBoardID* outputArr, uint16_t outputArrayLen) {
Expand All @@ -284,9 +268,7 @@ uint16_t CanAutoNode::GetIDsOfAllBoards(CanAutoNode::UniqueBoardID* outputArr, u
break;
}
}

return num;

}

CanAutoNode::UniqueBoardID CanAutoNode::GetIDOfBoardWithName(const char* name) {
Expand Down Expand Up @@ -314,7 +296,6 @@ uint16_t CanAutoNode::GetNumberOfLogIndicesInBoard(UniqueBoardID board) {
}
}
return 0;

}

uint16_t CanAutoNode::GetSizeOfLogIndexInBoard(UniqueBoardID board, uint16_t logindex) {
Expand Down
53 changes: 38 additions & 15 deletions CanAutoNode/CanAutoNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,40 @@
* Define this to enable debug prints across the driver. Uses SOAR_PRINT.
*/
//#define CANAUTONODEDEBUG
//#define PACK_NETWORKLEVEL_CAN_STRUCTS

#ifdef CANAUTONODEDEBUG
#include "SystemDefines.hpp"
#endif

#include "FDCan.h"
#include <cstring>
#include <random>

constexpr uint32_t MAX_NODES_IN_NETWORK = 100;
constexpr uint8_t MAX_LOG_TYPES_PER_NODE = 5;
constexpr uint8_t MAX_NAME_STR_LEN = 20;
constexpr uint32_t MAX_NODES_IN_NETWORK = 20;
constexpr uint8_t MAX_LOG_TYPES_PER_NODE = 9;
constexpr uint8_t MAX_NAME_STR_LEN = 10;
constexpr uint8_t MAX_JOIN_ATTEMPTS = 8;
// Max 2047 for 11-bit standard FDCAN, max 536,870,911 for extended FDCAN.
// See transceiver and board capabilities before changing.
constexpr uint16_t MAX_CAN_ID = 2047;

// Reserved CAN IDs
constexpr uint16_t JOIN_REQUEST_ID = 0;
constexpr uint16_t ACK_ID = 1;
constexpr uint16_t UPDATE_ID = 2;
constexpr uint16_t KICK_REQUEST_ID = 3;
constexpr uint16_t HEARTBEAT_ID = 4;
constexpr uint16_t MAX_RESERVED_CAN_ID = 4; // Make sure to update if adding a new reserved ID

constexpr uint16_t JOIN_REQUEST_CAN_ID = 0;
constexpr uint16_t ACK_CAN_ID = 1;
constexpr uint16_t UPDATE_CAN_ID = 2;
constexpr uint16_t KICK_REQUEST_CAN_ID = 4;
constexpr uint16_t HEARTBEAT_CAN_ID = 5;
constexpr uint16_t MAX_RESERVED_CAN_ID = 5; // Make sure to update if adding a new reserved ID

constexpr uint16_t JOIN_REQUEST_RLOG_INDEX = 0;
constexpr uint16_t ACK_RLOG_INDEX = 1;
constexpr uint16_t UPDATE_RLOG_INDEX = 2;
constexpr uint16_t KICK_REQUEST_RLOG_INDEX = 3;
constexpr uint16_t HEARTBEAT_RLOG_INDEX = 4;
constexpr uint16_t MAX_RESERVED_RLOG_INDEX = 4; // Make sure to update if adding a new reserved ID

constexpr uint16_t SEND_RECEIVE_ID_SPLIT_AMOUNT = 0;

#ifdef CANAUTONODEDEBUG
//#include "Task.hpp"
Expand All @@ -49,7 +62,6 @@ class CanAutoNode {
CanAutoNode(CanAutoNode &&other) = delete;
CanAutoNode& operator=(const CanAutoNode &other) = delete;


enum updateType {
CAN_UPDATE_DAUGHTER,
CAN_UPDATE_LAST_DAUGHTER,
Expand All @@ -70,7 +82,6 @@ class CanAutoNode {

bool operator==(const UniqueBoardID&) const = default;
bool operator!=(const UniqueBoardID&) const = default;

};

bool SendMessageToDaughterByLogIndex(UniqueBoardID boardID, uint8_t logIndex, const uint8_t* msg);
Expand Down Expand Up @@ -110,6 +121,9 @@ class CanAutoNode {
bool operator!=(const IDRange&) const = default;
};

#ifdef PACK_NETWORKLEVEL_CAN_STRUCTS
#pragma pack(push,1)
#endif
struct Node {
IDRange canIDRange;
UniqueBoardID uniqueID = {0};
Expand All @@ -123,16 +137,20 @@ class CanAutoNode {

char nodeName[MAX_NAME_STR_LEN];

uint16_t startingLogIndexOnMotherboard = MAX_RESERVED_CAN_ID+1;
uint16_t startingLogIndexOnMotherboard = MAX_RESERVED_RLOG_INDEX+1;

bool operator==(const Node&) const = default;
bool operator!=(const Node&) const = default;

};

static_assert(sizeof(Node) <= 64, "Node entries must be at most 64 bytes large. Try reducing MAX_LOGS");

struct HeartbeatInfo {
enum DIRECTION {
INVAL,
FROM_MOTH,
TO_MOTH
} dir;
UniqueBoardID senderBoardID;
};

Expand All @@ -146,6 +164,10 @@ class CanAutoNode {
uint8_t logSizesInBytes[MAX_LOG_TYPES_PER_NODE];
};

#ifdef PACK_NETWORKLEVEL_CAN_STRUCTS
#pragma pack(pop)
#endif

static_assert(sizeof(JoinRequest) <= 64, "Join request entries must be at most 64 bytes large. Try reducing MAX_LOGS");

FDCanController* controller = nullptr;
Expand Down Expand Up @@ -179,10 +201,11 @@ class CanAutoNode {

bool ReadMessageFromRXBuf(uint8_t logIndex, uint16_t logSize, uint8_t* out, uint16_t outLen);

virtual HeartbeatInfo::DIRECTION GetDir() const = 0;

private:
CanAutoNode(const CanAutoNode &other) = delete;


};

#endif /* AUTONODE_CANAUTONODE_HPP_ */
Loading