oliverlee / phobos

TU Delft bike lab embedded systems projects
http://spaaaccccce.com/Space_space_space_Going_Going_there_Okay_I_love_you_space_Yeah_yeah_yeah_okay_okay_Atmosphere_Black_holes_Astronauts_Nebulas_Jupiter_The_Big_Dipper_Im_proud_of_you_son_Space_space_wanna_go_to_space
BSD 2-Clause "Simplified" License
1 stars 5 forks source link

Add 2-way communication #310

Open oliverlee opened 6 years ago

oliverlee commented 6 years ago

We've talked about this for a while and want to implement 2-way communication to fix a number of issues which include:

This would involve defining messages as described in the following PRs: https://github.com/oliverlee/phobos/issues/181, https://github.com/oliverlee/phobos/issues/153, https://github.com/oliverlee/phobos/issues/235

I imagine we would need to introduce a simple state machine with the following states:

INIT: Program entry and sensor and actuator initialization. We would want to initialize and start the motor here and command a torque of zero so that we could restart the simulation without motor problems.

STOP: Reset all state associated with model and controller.

CONFIG: Configure model and controller parameters.

RUN: Run simulation.

For message, we differentiate between COMMAND and DATA types where a COMMAND message is simply a tag and a DATA message is a tag followed by an object as described in https://github.com/oliverlee/phobos/issues/181#issuecomment-301825244.

In order to fully implement this, I expect we need the following PRs:

mickvangelderen commented 6 years ago
oliverlee commented 6 years ago

Why are STOP and CONFIG different states?

I think you're right and they don't need to be.

Can the velocity be changed on the fly with this setup? Should we differentiate between parameters that cannot be changed in real time and ones that can?

Yes maybe we should have a config message for things that can be updated and things that cannot. At this time, I think all the fields that can be set can be changed in real time.

Can we name the states more like states instead of commands, like INITIALIZING, STOPPED, RUNNING

👍

mickvangelderen commented 6 years ago

Protobuf rework

Definitions

MC: The embedded microcontroller. PC: The pc to which the microcontroller is connected.

Code architecture

Add a receive thread to the MC. This thread is kept as dumb as possible. It is responsible for deserializing protobuf messages and enqueueing them for the simulation thread. It ignores deserialization errors.

The simulation thread will, while there is time left before the next deadline, dequeue messages that represent commands. These commands can stop or start the simulation or change certain parameters. when parameters are changed, an acknowledgement message must be enqueued for the transmitter thread containing a timestamp and the changed parameters. Large changes in parameters might have undesirable physical consequences. For now it is the responsibility of the PC to gradually change these parameters. The MC does have to check for nonsensical values.

These acknowledgement messages are also used during initialization to inform the PC of the initial configuration.

Message design

Configuration commands are defined for each set of configurable variables that must be changed all at once. This makes it easier to ensure sensible values are used in every simulation iteration. If values can be changed independently they should be changeable through different commands. This keeps the system flexible and the message size down which helps when defining memory pools.

The following observations motivate the creation of two separate memory pools to allocate messages from:

We need several grouping oneof messages: (A) 1x PC to receive thread to simulation thread, 2x (B, C) simulation thread to transmit thread. (D) 1x transmit thread to PC.

The simplest approach to combine B, C would be to nest them inside D. Instead we embed the variants of B and C directly into D. Extending oneof is not supported but this might allow us to do memcpy CHECK THIS. Perhaps it is possible to handwrite part of the encoding so we can serialize directly from the memory pool objects CHECK THIS.

TODO: Revisit optional fields. Thought it would be nice to have everything optional so that the steerbywire could also be connected to the visualizer and just show what ever values are present.

oliverlee commented 6 years ago

Maximum encoded message sizes (079c530) pbSimulation_size: 400 pbPose_size: 35 pbBuild_size: 29 pbModelCanonical_size: (24 + 4*pbSecondOrderMatrix_size) = 104

/* pbRxMaster_size depends on runtime parameters */
/* pbSmallMessageGroup_size depends on runtime parameters */
/* pbTxMaster_size depends on runtime parameters */

Extending oneof is not supported but this might allow us to do memcpy CHECK THIS

Yes this should be possible due to the memory layout.

oliverlee commented 6 years ago

Here are the other sizes after fixing nanopb generation

#define pbEmpty_size                             0
#define pbModelCanonical_size                    88
#define pbFeedbackGains_size                     15
#define pbRxMaster_size                          90
#define pbSmallMessageGroup_size                 90
#define pbTxMaster_size                          409
oliverlee commented 6 years ago

I think we want to split pbModelCanonical into multiple messages as it is larger than the others, even though it is unlikely we want to set the matrices individually.

mickvangelderen commented 6 years ago

multiple messages as it is larger than the others, even though it is unlikely we want to set the matrices individually

It is desirable from the implementation point of view, but we can only do it iff

Configuration commands are defined for each set of configurable variables that must be changed all at once. This makes it easier to ensure sensible values are used in every simulation iteration. If values can be changed independently they should be changeable through different commands.