Sent with QoS 0.
This is the lowest level of messages. It will be sent at any relevant state change.
A relevant state change is for example if the tracked cards have changed, but not if
the position of a card is updated.
NOTE: If you need a live stream of the card positions the updates quickly and
continuously, use the card_positions topic.
NOTE: In the future we plan to expose an Idle state and a CardPrep state to give you
more information on the table state. We will do so once this functionality matures in
our own use cases. Feedback is always welcome.
This is the full data structure describing the live state of the table.
We don't distinguish between a summary data structure for a complete round and the live
data structure.
You can treat this data structure with one of the final game phases as the summary
data structure.
players
The length of this list is fixed and determined with the calibration procedure.
NOTE: Don't rely on this being constant for a single configuration, even though it
is currently. Also, the system can be recalibrated at any time, changing the length
of this list.
dealer
All the information about the dealer.
layout_side_bets
If side bets are configured, the stacks assigned to them are listed here.
lifetime
The number of frames since the round was initialized
diagnostics
This contains warnings about procedure issues
initialized_ts
The timestamp when this round was initialized. It can be initialized by the detection
of game objects like cards, chip stacks and bills.
phase_timestamps
The timestamps for when each phase change.
If a phase is not present in the dict, it means it has not started.
A phase can also be present multiple times if a card is not seen anymore
and we decide that it is better to go to a previous phase.
cash
This is currently a flat list of the bills that we estimate are currently present.
NOTE: in the future we want to add structure to it and identify cash transactions.
id
UUID v4. It is generated each new round. A round starts as soon as anything relevant
is detected. Currently 'anything relevant' means cards, chips, or cash.
The latter two are only considered if these models are deployed and configured.
Not every UUID should be treated as a full round, it might be canceled and never reach
RoundOver but only RoundCanceled.
Example: A chip stack is recognized and then disappears.
This describes the current game phase.
Note: It doesn't always move forward. Sometimes the system will correct itself
due to cards being occluded or intentionally moved.
The round starts as EMPTY.
Once a card is detected we go to PRE_FIRST_CARDS and once it is assigned to a player
or dealer, we enter FIRST_CARDS.
When the dealer has a card, and all players have 2 cards we go to PLAYERS_TURN.
In this state the players do all their actions.
DEALERS_TURN is the dealers turn.
When the round is over we go to DEALER_DONE.
In some situations we cannot determine if the round is over without more context
so we go to DEALER_MAYBE_DONE. For example: All players have busted,
but the dealer has to finish playing the hand anyways because of a side bet.
At the end we will go into ROUND_OVER if the round is supposed to be stored, and into
ROUND_CANCELED if we classify it as sensor noise.
This state will only be reached once, you should not miss this event.
We use this to mark what rounds we store in the database or show on the screen.
Even rounds with wrong dealer procedure will reach ROUND_OVER, they are marked
as such in the anomalies / diagnostics fields.
This structure contains all player specific information.
stacks
This refers to the card stack, and the chips associated to this stack of cards.
A player can have 0 stacks, which means that it is inactive.
A player can have >1 stack, when they split their cards.
initial_bets
When the round starts and players place their bets, the chip stacks are tracked
as initial bets here.
The initial bets for the next round are also tracked here.
payout_stacks
After the dealer is done, stacks can be identified as being a payout and they will
be tracked in this field.
NOTE: We are not yet tracking payouts on a per bet level, but a per player level.
side_bets
This will track the chip stacks for each configured player side bet.
Must contain a minimum of 0 items
The word stack refers to card stack and the associated chip stacks.
A stack is usually part of a player data structure or a dealer data structure.
There is no distinction between a dealer stack and a player stack as of now on
the data modelling level.
cards
Here we track the cards belonging to this stack. This list is never empty.
NOTE: The cards might be deleted from here in the same round. This is supposed to
happen when a dealer drops a card, it got assigned to a stack, and then quickly moves
the card somewhere else.
is_doubled
We take multiple indicators to decide if a stack was doubled including:
- card rotation
- card placement
- chip stacks
main_bet_stacks
These are the chip stacks that we think are the main bet for this card stack.
There are multiple chip stacks here if a player doubled, or is about to split.
In case of a split: The main bet stacks are then splitted up to each stack.
back_bet_stacks
In Europe it is common to allow other people to bet on your hand with a bet position
calld back bet. The semantics are similar to the main_bet_stacks.
Must contain a minimum of 1 items
Describes a playing card.
The keypoints are the corners of the rectangle. This is actually a parallelogram as
of today, but don't rely on it.
rotation is measured as the angle in degrees between the longer axis with the
y-axis (the second coordinate).
Must contain a minimum of 4 items
Must contain a maximum of 4 items
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Evidence is a measure for how sure the system is about the label.
Currently it is unstable and the range is undocumented.
This data is tracked over time. Don't rely too much on it, e.g. hit_counter_max might
change during the lifetime of a tracked object.
The fields start and stop are useful to understand when in a round this object
was seen. They are given in the number of frames since initialization.
Note: In the future these might be fully timestamped.
Describes a stack of chips (without counting, just stating its presence).
lt stands for the left top corner and rb for the right bottom corner.
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Evidence is a measure for how sure the system is about the label.
Currently it is unstable and the range is undocumented.
This data is tracked over time. Don't rely too much on it, e.g. hit_counter_max might
change during the lifetime of a tracked object.
The fields start and stop are useful to understand when in a round this object
was seen. They are given in the number of frames since initialization.
Note: In the future these might be fully timestamped.
Describes a stack of chips (without counting, just stating its presence).
Same definition as ChipStackAPIDescribes a stack of chips (without counting, just stating its presence).
Same definition as ChipStackAPIDescribes a stack of chips (without counting, just stating its presence).
Same definition as ChipStackAPIMust contain a minimum of 2 items
Must contain a maximum of 2 items
Describes a stack of chips (without counting, just stating its presence).
Same definition as ChipStackAPIThis structure contains the dealer specific information.
stack is None while the dealer doesn't have any cards.
The word stack refers to card stack and the associated chip stacks.
A stack is usually part of a player data structure or a dealer data structure.
There is no distinction between a dealer stack and a player stack as of now on
the data modelling level.
cards
Here we track the cards belonging to this stack. This list is never empty.
NOTE: The cards might be deleted from here in the same round. This is supposed to
happen when a dealer drops a card, it got assigned to a stack, and then quickly moves
the card somewhere else.
is_doubled
We take multiple indicators to decide if a stack was doubled including:
- card rotation
- card placement
- chip stacks
main_bet_stacks
These are the chip stacks that we think are the main bet for this card stack.
There are multiple chip stacks here if a player doubled, or is about to split.
In case of a split: The main bet stacks are then splitted up to each stack.
back_bet_stacks
In Europe it is common to allow other people to bet on your hand with a bet position
calld back bet. The semantics are similar to the main_bet_stacks.
Must contain a minimum of 2 items
Must contain a maximum of 2 items
Describes a stack of chips (without counting, just stating its presence).
Same definition as ChipStackAPIMust contain a minimum of 2 items
Must contain a maximum of 2 items
A timestamp includes the date_time and the frame number since round initialization.
Don't assume that the timezone is correct, it will fall back to UTC.
A card was seen where it was not expected.
NOTE: This will include the duration for how long that was in the future.
A card was seen where it was not expected while it was the dealers turn.
NOTE: This will include the duration for how long that was in the future.
Given the configured rules, the dealer should have drawn another card.
Given the configured rules, the dealer drew a card too many.
A card for the players was missing.
A timestamp includes the date_time and the frame number since round initialization.
Don't assume that the timezone is correct, it will fall back to UTC.
Must contain a minimum of 2 items
Must contain a maximum of 2 items
A timestamp includes the date_time and the frame number since round initialization.
Don't assume that the timezone is correct, it will fall back to UTC.
This describes the current game phase.
Note: It doesn't always move forward. Sometimes the system will correct itself
due to cards being occluded or intentionally moved.
The round starts as EMPTY.
Once a card is detected we go to PRE_FIRST_CARDS and once it is assigned to a player
or dealer, we enter FIRST_CARDS.
When the dealer has a card, and all players have 2 cards we go to PLAYERS_TURN.
In this state the players do all their actions.
DEALERS_TURN is the dealers turn.
When the round is over we go to DEALER_DONE.
In some situations we cannot determine if the round is over without more context
so we go to DEALER_MAYBE_DONE. For example: All players have busted,
but the dealer has to finish playing the hand anyways because of a side bet.
At the end we will go into ROUND_OVER if the round is supposed to be stored, and into
ROUND_CANCELED if we classify it as sensor noise.
This state will only be reached once, you should not miss this event.
We use this to mark what rounds we store in the database or show on the screen.
Even rounds with wrong dealer procedure will reach ROUND_OVER, they are marked
as such in the anomalies / diagnostics fields.
Describes a single bill of cash.
The keypoints are the corners of the rectangle. This is actually a parallelogram as
of today, but don't rely on it.
rotation is measured as the angle in degrees between the longer axis with the
y-axis (the second coordinate).
Evidence is a measure for how sure the system is about the label.
Currently it is unstable and the range is undocumented.
This data is tracked over time. Don't rely too much on it, e.g. hit_counter_max might
change during the lifetime of a tracked object.
The fields start and stop are useful to understand when in a round this object
was seen. They are given in the number of frames since initialization.
Note: In the future these might be fully timestamped.