src/droneModules/ControllerModule.cpp
/*

Menu structure:

NB: will attempt to load last binding at startup

Root = info for active binding OR indicator that is unbound
  Load config
    * Select config to load (from SPIFFS)

  Start new config
    * List of nodes to create binding (from DroneLinkManager nodeInfo map)
    * Selecting a node establishes an empty binding and goes to edit binding menu

  Edit current binding
    * Shows the list of control axes and their current bindings - i.e. the 6 joystick axes
    * Pick an axes to edit or establish a binding
    Edit Axis menu
      Bind -> Select module
        * Shows a list of modules available on the target node (continuously discovered in background)
        Select parameter
          * Shows a list of parameters for the selected module (continusouly discovered in background)
          * Once selected, creates the binding and returns to the Edit Current Binding menu
      Remove binding (if already bound)

  Save current binding (only available if a binding is active)
    * Saves current binding (using node name as reference) and sets flag for last used config


  Edit info map
    * Once a binding is completed


*/
Menu structure:
NB: will attempt to load last binding at startup

Root = info for active binding OR indicator that is unbound
Load config
Select config to load (from SPIFFS)

Start new config
List of nodes to create binding (from DroneLinkManager nodeInfo map)
Selecting a node establishes an empty binding and goes to edit binding menu

Edit current binding
Shows the list of control axes and their current bindings - i.e. the 6 joystick axes
Pick an axes to edit or establish a binding
Edit Axis menu
Bind -> Select module
Shows a list of modules available on the target node (continuously discovered in background)
Select parameter
Shows a list of parameters for the selected module (continusouly discovered in background)
Once selected, creates the binding and returns to the Edit Current Binding menu
Remove binding (if already bound)

Save current binding (only available if a binding is active)
Saves current binding (using node name as reference) and sets flag for last used config

Edit info map
Once a binding is completed
Menu structure : NB : will attempt to load last binding at startup Root = info for active binding OR indicator that is unbound Load config Select config to load ( from SPIFFS ) Start new config List of nodes to create binding ( from DroneLinkManager nodeInfo map ) Selecting a node establishes an empty binding and goes to edit binding menu Edit current binding Shows the list of control axes and their current bindings - i . e . the 6 joystick axes Pick an axes to edit or establish a binding Edit Axis menu Bind - > Select module Shows a list of modules available on the target node ( continuously discovered in background ) Select parameter Shows a list of parameters for the selected module ( continusouly discovered in background ) Once selected creates the binding and returns to the Edit Current Binding menu Remove binding ( if already bound ) Save current binding ( only available if a binding is active ) Saves current binding ( using node name as reference ) and sets flag for last used config Edit info map Once a binding is completed
ControllerModule::ControllerModule(uint8_t id, DroneModuleManager* dmm, DroneLinkManager* dlm, DroneExecutionManager* dem, fs::FS &fs):
  I2CBaseModule ( id, dmm, dlm, dem, fs )
 {
   setTypeName(FPSTR(CONTROLLER_STR_CONTROLLER));
   _queryMsg.source(_dlm->node());
   _queryMsg.type(DRONE_LINK_MSG_TYPE_NAMEQUERY);
   _queryMsg.length(1);
   _queryMsg._msg.payload.uint8[0] = 0;
   _sendMsg.source(_dlm->node());
   _sendMsg.type(DRONE_LINK_MSG_TYPE_FLOAT);
   _sendMsg.writable(false);
   _sendMsg.length(4);
   _sendMsg._msg.payload.f[0] = 0;
   _brightness = 0;
   _spinner = 0;
   _cellVoltage = 0;
   _batteryCapacity = 0;
   _display = NULL;
   _RSSI = 0;
   _menu = CONTROLLER_MENU_ROOT;
   _scroll = 0;
   _syncMenusTimer = 0;
   _lastDiscovery = 0;
   for (uint8_t i=0; i<CONTROLLER_MENU_COUNT; i++) {
     _menus[i].selected = 0;
   }
   clear();
   initParams(CONTROLLER_PARAM_ENTRIES);
   I2CBaseModule::initBaseParams();
   _params[I2CBASE_PARAM_ADDR_E].data.uint8[0] = CONTROLLER_OLED_I2C_ADDRESS;
   DRONE_PARAM_ENTRY *param;
   param = &_params[CONTROLLER_PARAM_LEFT_E];
   param->paramPriority = setDroneLinkMsgPriorityParam(DRONE_LINK_MSG_PRIORITY_LOW, CONTROLLER_PARAM_LEFT);
   setParamName(FPSTR(STRING_LEFT), param);
   param->paramTypeLength = _mgmtMsg.packParamLength(true, DRONE_LINK_MSG_TYPE_UINT8_T, 1);
   param->data.uint8[0] = 4;
   param = &_params[CONTROLLER_PARAM_RIGHT_E];
   param->paramPriority = setDroneLinkMsgPriorityParam(DRONE_LINK_MSG_PRIORITY_LOW, CONTROLLER_PARAM_RIGHT);
   setParamName(FPSTR(STRING_RIGHT), param);
   param->paramTypeLength = _mgmtMsg.packParamLength(true, DRONE_LINK_MSG_TYPE_UINT8_T, 1);
   param->data.uint8[0] = 5;
   param = &_params[CONTROLLER_PARAM_TELEMETRY_E];
   param->paramPriority = setDroneLinkMsgPriorityParam(DRONE_LINK_MSG_PRIORITY_LOW, CONTROLLER_PARAM_TELEMETRY);
   setParamName(FPSTR(STRING_TELEMETRY), param);
   param->paramTypeLength = _mgmtMsg.packParamLength(true, DRONE_LINK_MSG_TYPE_UINT8_T, 1);
   param->data.uint8[0] = 6;
   param = &_params[CONTROLLER_PARAM_POWER_E];
   param->paramPriority = setDroneLinkMsgPriorityParam(DRONE_LINK_MSG_PRIORITY_LOW, CONTROLLER_PARAM_POWER);
   setParamName(FPSTR(STRING_POWER), param);
   param->paramTypeLength = _mgmtMsg.packParamLength(true, DRONE_LINK_MSG_TYPE_UINT8_T, 1);
   param->data.uint8[0] = 9;
}
ControllerModule :: ControllerModule ( uint8_t id , DroneModuleManager * dmm , DroneLinkManager * dlm , DroneExecutionManager * dem , fs :: FS & fs ) : I2CBaseModule ( id , dmm , dlm , dem , fs ) { setTypeName ( FPSTR ( CONTROLLER_STR_CONTROLLER ) ) ; _queryMsg . source ( _dlm -> node ( ) ) ; _queryMsg . type ( DRONE_LINK_MSG_TYPE_NAMEQUERY ) ; _queryMsg . length ( 1 ) ; _queryMsg . _msg . payload . uint8 [ 0 ] = 0 ; _sendMsg . source ( _dlm -> node ( ) ) ; _sendMsg . type ( DRONE_LINK_MSG_TYPE_FLOAT ) ; _sendMsg . writable ( false ) ; _sendMsg . length ( 4 ) ; _sendMsg . _msg . payload . f [ 0 ] = 0 ; _brightness = 0 ; _spinner = 0 ; _cellVoltage = 0 ; _batteryCapacity = 0 ; _display = NULL ; _RSSI = 0 ; _menu = CONTROLLER_MENU_ROOT ; _scroll = 0 ; _syncMenusTimer = 0 ; _lastDiscovery = 0 ; for ( uint8_t i = 0 ; i < CONTROLLER_MENU_COUNT ; i ++ ) { _menus [ i ] . selected = 0 ; } clear ( ) ; initParams ( CONTROLLER_PARAM_ENTRIES ) ; I2CBaseModule :: initBaseParams ( ) ; _params [ I2CBASE_PARAM_ADDR_E ] . data . uint8 [ 0 ] = CONTROLLER_OLED_I2C_ADDRESS ; DRONE_PARAM_ENTRY * param ; param = & _params [ CONTROLLER_PARAM_LEFT_E ] ; param -> paramPriority = setDroneLinkMsgPriorityParam ( DRONE_LINK_MSG_PRIORITY_LOW , CONTROLLER_PARAM_LEFT ) ; setParamName ( FPSTR ( STRING_LEFT ) , param ) ; param -> paramTypeLength = _mgmtMsg . packParamLength ( true , DRONE_LINK_MSG_TYPE_UINT8_T , 1 ) ; param -> data . uint8 [ 0 ] = 4 ; param = & _params [ CONTROLLER_PARAM_RIGHT_E ] ; param -> paramPriority = setDroneLinkMsgPriorityParam ( DRONE_LINK_MSG_PRIORITY_LOW , CONTROLLER_PARAM_RIGHT ) ; setParamName ( FPSTR ( STRING_RIGHT ) , param ) ; param -> paramTypeLength = _mgmtMsg . packParamLength ( true , DRONE_LINK_MSG_TYPE_UINT8_T , 1 ) ; param -> data . uint8 [ 0 ] = 5 ; param = & _params [ CONTROLLER_PARAM_TELEMETRY_E ] ; param -> paramPriority = setDroneLinkMsgPriorityParam ( DRONE_LINK_MSG_PRIORITY_LOW , CONTROLLER_PARAM_TELEMETRY ) ; setParamName ( FPSTR ( STRING_TELEMETRY ) , param ) ; param -> paramTypeLength = _mgmtMsg . packParamLength ( true , DRONE_LINK_MSG_TYPE_UINT8_T , 1 ) ; param -> data . uint8 [ 0 ] = 6 ; param = & _params [ CONTROLLER_PARAM_POWER_E ] ; param -> paramPriority = setDroneLinkMsgPriorityParam ( DRONE_LINK_MSG_PRIORITY_LOW , CONTROLLER_PARAM_POWER ) ; setParamName ( FPSTR ( STRING_POWER ) , param ) ; param -> paramTypeLength = _mgmtMsg . packParamLength ( true , DRONE_LINK_MSG_TYPE_UINT8_T , 1 ) ; param -> data . uint8 [ 0 ] = 9 ; }
Menu structure:
NB: will attempt to load last binding at startup
Menu structure : NB : will attempt to load last binding at startup
// init query msg // configure menus // defaults // subs // outputs