Fang-Robotics-MCB
Fang Robotics Team Codebase
Loading...
Searching...
No Matches
tap::can::CanRxHandler Class Reference

#include <can_rx_handler.hpp>

Collaboration diagram for tap::can::CanRxHandler:

Public Member Functions

 CanRxHandler (Drivers *drivers)
 
mockable ~CanRxHandler ()=default
 
mockable void attachReceiveHandler (CanRxListener *const listener)
 
mockable void pollCanData ()
 
mockable void removeReceiveHandler (const CanRxListener &rxListener)
 

Static Public Member Functions

static uint16_t binIndexForCanId (uint16_t canId)
 

Static Public Attributes

static constexpr uint8_t CAN_BINS = 8
 

Protected Member Functions

void attachReceiveHandler (CanRxListener *const canRxListener, CanRxListener **messageHandlerStore)
 
void processReceivedCanData (const modm::can::Message &rxMessage, CanRxListener *const *messageHandlerStore)
 
void removeReceiveHandler (const CanRxListener &canRxListener, CanRxListener **messageHandlerStore)
 
CanRxListener ** getHandlerStore (CanBus bus)
 

Protected Attributes

Driversdrivers
 
CanRxListenermessageHandlerStoreCan1 [CAN_BINS]
 
CanRxListenermessageHandlerStoreCan2 [CAN_BINS]
 

Detailed Description

A handler that stores pointers to CanRxListener and that watches CAN 1 and CAN 2 for messages. If messages are received, it checks its internal maps for a CanRxListener that matches the message identifier and CAN bus and calls the listener's processMessage function.

Interfaces with modm receive data from CAN1 and CAN2 buses.

To use, extend CanRxListener class and create a method called processMessage. Next, call the function attachReceiveHandler, which will add the class you instantiated to a list of classes that will be handled on receive. The class you created and attached will be called by the pollCanData function every time there is a message available that has the CAN identifier matching the identifier specified in the CanRxListener constructor.

For proper closed loop motor control, it is necessary to have the pollCanData function be called at a very high frequency, so call this in a high frequency thread.

Note
CAN ids [0x201, 0x20B] are used by the DjiMotor objects to receive data from DJI branded motors. If you would like to define your own protocol, it is recommended to avoid avoid using CAN ids in this range.
the DjiMotor driver reserves 0x1FF and 0x200 for commanding motors, and thus you should not attach listeners for these ids.
See also
CanRxListener for information about how to properly create add a listener to the handler.
Can for modm CAN wrapper functions.

Constructor & Destructor Documentation

◆ CanRxHandler()

tap::can::CanRxHandler::CanRxHandler ( Drivers drivers)

◆ ~CanRxHandler()

mockable tap::can::CanRxHandler::~CanRxHandler ( )
default

Member Function Documentation

◆ attachReceiveHandler() [1/2]

void tap::can::CanRxHandler::attachReceiveHandler ( CanRxListener *const  canRxListener,
CanRxListener **  messageHandlerStore 
)
protected

◆ attachReceiveHandler() [2/2]

void tap::can::CanRxHandler::attachReceiveHandler ( CanRxListener *const  listener)

Call this function to add a CanRxListener to the list of CanRxListener's that are referenced when a new CAN message is received.

Note
do not call this function in an object that is globally (i.e. not on that stack or heap) constructed. The map that the handler uses to store listeners may or not be properly allocated if you do and undefined behavior will follow.
if you attempt to add a listener with an identifier identical to something already in the CanRxHandler, an error will be added to the ErrorController and the handler does not add the listener.
See also
CanRxListener
Parameters
[in]listenerthe listener to be attached ot the handler.

◆ binIndexForCanId()

static uint16_t tap::can::CanRxHandler::binIndexForCanId ( uint16_t  canId)
inlinestatic

Given a CAN identifier, returns the bin index between [0, NUM_CAN_IDS) for the identifier.

◆ getHandlerStore()

CanRxListener ** tap::can::CanRxHandler::getHandlerStore ( CanBus  bus)
inlineprotected

◆ pollCanData()

void tap::can::CanRxHandler::pollCanData ( )

Function handles receiving messages and calling the appropriate processMessage function given the CAN bus and can identifier.

Attention
you should call this function as frequently as you receive messages if you want to receive the most up to date messages. modm's IQR puts CAN messages in a queue, and this function clears out the queue once it is called.

◆ processReceivedCanData()

void tap::can::CanRxHandler::processReceivedCanData ( const modm::can::Message &  rxMessage,
CanRxListener *const *  messageHandlerStore 
)
protected

◆ removeReceiveHandler() [1/2]

void tap::can::CanRxHandler::removeReceiveHandler ( const CanRxListener canRxListener,
CanRxListener **  messageHandlerStore 
)
protected

◆ removeReceiveHandler() [2/2]

void tap::can::CanRxHandler::removeReceiveHandler ( const CanRxListener rxListener)

Removes the passed in CanRxListener from the CanRxHandler. If the listener isn't in the handler, an error will be added to the ErrorController and the state of the CanRxHandler will not change.

Parameters
[in]rxListenerThe listener to remove from the handler.

Member Data Documentation

◆ CAN_BINS

constexpr uint8_t tap::can::CanRxHandler::CAN_BINS = 8
staticconstexpr

The number of "hash" bins to store listeners in. 8 is choosen as most users will only have DJI Motors on their can bus, reducing any unnecessary overhead storing empty bins. The bus also become saturated near this limit, so the performance hit of a linked list traversal is minimal.

◆ drivers

Drivers* tap::can::CanRxHandler::drivers
protected

◆ messageHandlerStoreCan1

CanRxListener* tap::can::CanRxHandler::messageHandlerStoreCan1[CAN_BINS]
protected

Stores pointers to the CanRxListeners for CAN 1, referenced when a new message is received.

◆ messageHandlerStoreCan2

CanRxListener* tap::can::CanRxHandler::messageHandlerStoreCan2[CAN_BINS]
protected

Stores pointers to the CanRxListeners for CAN 2, referenced when a new message is received.


The documentation for this class was generated from the following files: