added local pool doc
This commit is contained in:
parent
35825a6561
commit
8de33f1301
@ -1,4 +1,4 @@
|
|||||||
## Local Data Pools
|
## Local Data Pools Developer Information
|
||||||
|
|
||||||
The local data pools can be used to store data like sensor values so they can be used
|
The local data pools can be used to store data like sensor values so they can be used
|
||||||
by other software objects like controllers as well. If a class should have a local pool which
|
by other software objects like controllers as well. If a class should have a local pool which
|
||||||
@ -20,10 +20,136 @@ access to the pool data is done via proxy classes like pool variable classes or
|
|||||||
Generally, a user will create a dataset class which in turn groups all cohesive pool variables.
|
Generally, a user will create a dataset class which in turn groups all cohesive pool variables.
|
||||||
|
|
||||||
The user can then use this set class to `read` the variables and `commit` changed variables
|
The user can then use this set class to `read` the variables and `commit` changed variables
|
||||||
back into the pool.
|
back into the pool. The general approach is that a user will create a header containing the set
|
||||||
|
class. For example, the following code shows an implementation to access data from a Gyroscope:
|
||||||
|
|
||||||
### Using the local data pools of the `DeviceHandlerBase`
|
```cpp
|
||||||
|
class GyroPrimaryDataset: public StaticLocalDataSet<3 * sizeof(float)> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor for data users
|
||||||
|
* @param gyroId
|
||||||
|
*/
|
||||||
|
GyroPrimaryDataset(object_id_t gyroId):
|
||||||
|
StaticLocalDataSet(sid_t(gyroId, gyrodefs::GYRO_DATA_SET_ID)) {
|
||||||
|
setAllVariablesReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
lp_var_t<float> angVelocityX = lp_var_t<float>(sid.objectId,
|
||||||
|
gyrodefs::ANGULAR_VELOCITY_X, this);
|
||||||
|
lp_var_t<float> angVelocityY = lp_var_t<float>(sid.objectId,
|
||||||
|
gyrodefs::ANGULAR_VELOCITY_Y, this);
|
||||||
|
lp_var_t<float> angVelocityZ = lp_var_t<float>(sid.objectId,
|
||||||
|
gyrodefs::ANGULAR_VELOCITY_Z, this);
|
||||||
|
private:
|
||||||
|
|
||||||
|
friend class GyroHandler;
|
||||||
|
/**
|
||||||
|
* Constructor for data creator
|
||||||
|
* @param hkOwner
|
||||||
|
*/
|
||||||
|
GyroPrimaryDataset(HasLocalDataPoolIF* hkOwner):
|
||||||
|
StaticLocalDataSet(hkOwner, gyrodefs::GYRO_DATA_SET_ID) {}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
There is a constructor for users which sets all variables to read-only and there is the constructor
|
||||||
|
for the GyroHandler data creator. Both the atittude controller and the `GyroHandler` can now
|
||||||
|
use the same class definition to access the pool variables with `read` and `commit` semantics
|
||||||
|
in a thread-safe way. Generally, each class requiring access will have the set class as a member
|
||||||
|
class. The data creator will also be generally a `DeviceHandlerBase` subclass and some additional
|
||||||
|
steps are necessary to expose the set for housekeeping purposes.
|
||||||
|
|
||||||
|
### Using the local data pools in a `DeviceHandlerBase` subclass
|
||||||
|
|
||||||
It is very common to store data generated by devices like a sensor into a pool which can
|
It is very common to store data generated by devices like a sensor into a pool which can
|
||||||
then be used by other objects. Therefore, the `DeviceHandlerBase` already has a
|
then be used by other objects. Therefore, the `DeviceHandlerBase` already has a
|
||||||
local pool. The
|
local pool. Using the aforementioned example, our `GyroHandler` will now have the set class
|
||||||
|
as a member:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class GyroHandler: ... {
|
||||||
|
|
||||||
|
public:
|
||||||
|
...
|
||||||
|
private:
|
||||||
|
...
|
||||||
|
GyroPrimaryDataset gyroData;
|
||||||
|
...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The constructor used for the creators expects the owner class as a parameter, so we initialize
|
||||||
|
the object in the `GyroHandler` constructor like this:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
GyroHandler::GyroHandler(object_id_t objectId, object_id_t comIF,
|
||||||
|
CookieIF *comCookie, uint8_t switchId):
|
||||||
|
DeviceHandlerBase(objectId, comIF, comCookie), switchId(switchId),
|
||||||
|
gyroData(this) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
We need to assign the set to a reply ID used in the `DeviceHandlerBase`.
|
||||||
|
The combination of the `GyroHandler` object ID and the reply ID will be the 64-bit structure ID
|
||||||
|
`sid_t` and is used to globally identify the set, for example when requesting housekeeping data or
|
||||||
|
generating update messages. We need to assign our custom in some way so that the local pool manager
|
||||||
|
can access the custom data sets as well.
|
||||||
|
By default, the `getDataSetHandle` will take care of this tasks. The default implementation for a
|
||||||
|
`DeviceHandlerBase` subclass will use the internal command map to retrieve
|
||||||
|
a handle to a dataset from a given reply ID. Therefore,
|
||||||
|
we assign the set in the `fillCommandAndReplyMap` function:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void GyroHandler::fillCommandAndReplyMap() {
|
||||||
|
...
|
||||||
|
this->insertInCommandAndReplyMap(gyrodefs::GYRO_DATA, 3, &gyroData);
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, we need to create the actual pool entries as well, using the `initializeLocalDataPool`
|
||||||
|
function. Here, we also immediately subscribe for periodic housekeeping packets
|
||||||
|
with an interval of 4 seconds. They are still disabled in this example and can be enabled
|
||||||
|
with a housekeeping service command.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
ReturnValue_t GyroHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
|
LocalDataPoolManager &poolManager) {
|
||||||
|
localDataPoolMap.emplace(gyrodefs::ANGULAR_VELOCITY_X,
|
||||||
|
new PoolEntry<float>({0.0}));
|
||||||
|
localDataPoolMap.emplace(gyrodefs::ANGULAR_VELOCITY_Y,
|
||||||
|
new PoolEntry<float>({0.0}));
|
||||||
|
localDataPoolMap.emplace(gyrodefs::ANGULAR_VELOCITY_Z,
|
||||||
|
new PoolEntry<float>({0.0}));
|
||||||
|
localDataPoolMap.emplace(gyrodefs::GENERAL_CONFIG_REG42,
|
||||||
|
new PoolEntry<uint8_t>({0}));
|
||||||
|
localDataPoolMap.emplace(gyrodefs::RANGE_CONFIG_REG43,
|
||||||
|
new PoolEntry<uint8_t>({0}));
|
||||||
|
|
||||||
|
poolManager.subscribeForPeriodicPacket(gyroData.getSid(), false, 4.0, false);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, we have received some sensor data and converted them into the right format,
|
||||||
|
we can write it into the pool like this, using a guard class to ensure the set is commited back
|
||||||
|
in any case:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
PoolReadGuard readHelper(&gyroData);
|
||||||
|
if(readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
if(not gyroData.isValid()) {
|
||||||
|
gyroData.setValidity(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
gyroData.angVelocityX = angularVelocityX;
|
||||||
|
gyroData.angVelocityY = angularVelocityY;
|
||||||
|
gyroData.angVelocityZ = angularVelocityZ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the local data pools in a `ExtendedControllerBase` subclass
|
||||||
|
|
||||||
|
Coming soon
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user