Program Listing for File ref_serial_data.hpp
↰ Return to documentation for file (src/tap/communication/serial/ref_serial_data.hpp
)
/*
* Copyright (c) 2020-2021 Advanced Robotics at the University of Washington <robomstr@uw.edu>
*
* This file is part of Taproot.
*
* Taproot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Taproot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Taproot. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef TAPROOT_REF_SERIAL_DATA_HPP_
#define TAPROOT_REF_SERIAL_DATA_HPP_
#include <cinttypes>
#include <modm/architecture/interface/register.hpp>
#include "modm/architecture/utils.hpp"
#include "dji_serial.hpp"
namespace tap::communication::serial
{
class RefSerialData
{
public:
enum class RobotId : uint16_t
{
INVALID = 0,
RED_HERO = 1,
RED_ENGINEER = 2,
RED_SOLDIER_1 = 3,
RED_SOLDIER_2 = 4,
RED_SOLDIER_3 = 5,
RED_DRONE = 6,
RED_SENTINEL = 7,
RED_DART = 8,
RED_RADAR_STATION = 9,
BLUE_HERO = 101,
BLUE_ENGINEER = 102,
BLUE_SOLDIER_1 = 103,
BLUE_SOLDIER_2 = 104,
BLUE_SOLDIER_3 = 105,
BLUE_DRONE = 106,
BLUE_SENTINEL = 107,
BLUE_DART = 108,
BLUE_RADAR_STATION = 109
};
static inline bool isBlueTeam(RobotId id) { return id >= RobotId::BLUE_HERO; }
class RobotToRobotMessageHandler
{
public:
RobotToRobotMessageHandler() {}
virtual void operator()(const DJISerial::ReceivedSerialMessage &message) = 0;
};
class Rx
{
public:
enum class GameType : uint8_t
{
UNKNOWN = 0,
ROBOMASTER_RMUC = 1,
ROBOMASTER_RMUTC = 2,
ROBOMASTER_AI_CHALLENGE = 3,
ROBOMASTER_RMUL_3V3 = 4,
ROBOMASTER_RMUL_1V1 = 5,
};
enum class GameStage : uint8_t
{
PREMATCH = 0,
SETUP = 1,
INITIALIZATION = 2,
COUNTDOWN = 3,
IN_GAME = 4,
END_GAME = 5,
};
enum class GameWinner : uint8_t
{
DRAW = 0,
RED = 1,
BLUE = 2,
};
enum class SiteDartHit : uint8_t
{
NONE = 0,
OUTPOST = 1,
BASE_FIXED = 2,
BASE_RANDOM = 3
};
enum class SupplierOutletStatus : uint8_t
{
CLOSED = 0,
PREPARING = 1,
RELEASING = 2
};
enum class DartTarget : uint8_t
{
NONE_OR_OUTPOST = 0,
BASE_FIXED = 1,
BASE_RANDOM = 2
};
enum class ArmorId : uint8_t
{
FRONT = 0,
LEFT = 1,
REAR = 2,
RIGHT = 3,
TOP = 4,
};
enum class DamageType : uint8_t
{
ARMOR_DAMAGE = 0,
MODULE_OFFLINE = 1,
BARREL_OVER_SPEED = 2,
BARREL_OVERHEAT = 3,
CHASSIS_POWER_OVERRUN = 4,
COLLISION = 5,
};
enum class SiteData : uint32_t
{
RESTORATION_FRONT_OCCUPIED = modm::Bit0,
RESTORATION_INSIDE_OCCUPIED = modm::Bit1,
SUPPLIER_OCCUPIED = modm::Bit2,
POWER_RUNE_OCCUPIED = modm::Bit3,
SMALL_POWER_RUNE_ACTIVATED = modm::Bit4,
LARGER_POWER_RUNE_ACTIVIATED = modm::Bit5,
RING_OCCUPIED_TEAM = modm::Bit6,
RING_OCCUPIED_OPPONENT = modm::Bit7,
TRAPEZOID_R3_OCCUPIED_TEAM = modm::Bit8,
TRAPEZOID_R3_OCCUPIED_OPPONENT = modm::Bit9,
TRAPEZOID_R4_OCCUPIED_TEAM = modm::Bit10,
TRAPEZOID_R4_OCCUPIED_OPPONENT = modm::Bit11,
CENTRAL_BUFF_OCCUPIED_TEAM = modm::Bit30,
CENTRAL_BUFF_OCCUPIED_OPPONENT = modm::Bit31
};
MODM_FLAGS32(SiteData);
enum class RobotPower : uint8_t
{
GIMBAL_HAS_POWER = modm::Bit0,
CHASSIS_HAS_POWER = modm::Bit1,
SHOOTER_HAS_POWER = modm::Bit2,
};
MODM_FLAGS8(RobotPower);
enum class RFIDActivationStatus : uint32_t
{
BASE_BUFF = modm::Bit0,
ELEVATED_RING_OWN = modm::Bit1,
ELEVATED_RING_OPPONENT = modm::Bit2,
TRAPEZOID_R3_OWN = modm::Bit3,
TRAPEZOID_R3_OPPONENT = modm::Bit4,
TRAPEZOID_R4_OWN = modm::Bit5,
TRAPEZOID_R4_OPPONENT = modm::Bit6,
POWER_RUNE_ACTIVATION = modm::Bit7,
LAUNCH_RAMP_FRONT_OWN = modm::Bit8,
LAUNCH_RAMP_BACK_OWN = modm::Bit9,
LAUNCH_RAMP_FRONT_OPPONENT = modm::Bit10,
LAUNCH_RAMP_BACK_OPPONENT = modm::Bit11,
OUTPOST_BUFF = modm::Bit12,
RESTORATION_ZONE = modm::Bit13,
SENTRY_PATROL_OWN = modm::Bit14,
SENTRY_PATROL_OPPONENT = modm::Bit15,
LARGE_ISLAND_OWN = modm::Bit16,
LARGE_ISLAND_OPPONENT = modm::Bit17,
EXCHANGE_ZONE = modm::Bit18,
CENTRAL_BUFF = modm::Bit19
};
MODM_FLAGS32(RFIDActivationStatus);
struct DamageEvent
{
uint16_t damageAmount;
uint32_t timestampMs;
};
enum BulletType
{
AMMO_17 = 1,
AMMO_42 = 2,
};
enum MechanismID
{
TURRET_17MM_1 = 1,
TURRET_17MM_2 = 2,
TURRET_42MM = 3,
};
static constexpr int MAX_LAUNCH_SPEED_17MM = 30;
static constexpr int MAX_LAUNCH_SPEED_42MM = 16;
struct RobotHpData
{
struct RobotHp
{
uint16_t hero1;
uint16_t engineer2;
uint16_t standard3;
uint16_t standard4;
uint16_t standard5;
uint16_t sentry7;
uint16_t outpost;
uint16_t base;
};
RobotHp red;
RobotHp blue;
};
struct EventData
{
SiteData_t siteData;
uint8_t
virtualShieldRemainingPercent;
uint8_t timeSinceLastDartHit;
SiteDartHit lastDartHit;
};
struct SupplierAction
{
RobotId reloadingRobot;
SupplierOutletStatus outletStatus;
uint8_t suppliedProjectiles;
};
struct RobotPosition
{
float x;
float y;
};
struct ChassisData
{
uint16_t volt;
uint16_t current;
float power;
uint16_t powerBuffer;
RobotPosition position;
uint16_t powerConsumptionLimit;
};
struct TurretData
{
BulletType bulletType;
MechanismID launchMechanismID;
uint8_t firingFreq;
uint16_t heat17ID1;
uint16_t heat17ID2;
uint16_t heat42;
uint16_t heatLimit;
uint16_t coolingRate;
uint16_t bulletsRemaining17;
uint16_t bulletsRemaining42;
float bulletSpeed;
float yaw;
uint32_t lastReceivedLaunchingInfoTimestamp;
};
struct RobotBuffStatus
{
uint8_t recoveryBuff;
uint8_t coolingBuff;
uint8_t defenseBuff;
uint8_t
vulnerabilityBuff;
uint16_t attackBuff;
};
struct RefereeWarningData
{
uint8_t level;
RobotId foulRobotID;
uint8_t count;
uint32_t lastReceivedWarningRobotTime = 0;
static constexpr uint32_t OFFENDING_OPERATOR_BLIND_TIME = 5'000;
static constexpr uint32_t NONOFFENDING_OPERATOR_BLIND_TIME = 2'000;
};
struct DartInfo
{
uint8_t launchCountdown;
SiteDartHit lastHit;
uint8_t hits;
DartTarget selectedTarget;
};
enum AirSupportState : uint8_t
{
COOLING = 0,
COOLED = 1,
IN_AIR = 2
};
struct AirSupportData
{
AirSupportState state;
uint8_t remainingStateTime;
};
enum DartStationState : uint8_t
{
OPEN = 0,
CLOSED = 1,
TRANSITION = 2
};
struct DartStationInfo
{
DartStationState state;
uint16_t targetChangedTime;
uint16_t lastLaunchedTime;
};
struct GroundRobotPositions
{
RobotPosition hero;
RobotPosition engineer;
RobotPosition standard3;
RobotPosition standard4;
RobotPosition standard5;
};
struct RadarMarkProgress
{
uint8_t hero;
uint8_t engineer;
uint8_t standard3;
uint8_t standard4;
uint8_t standard5;
uint8_t sentry;
};
struct SentryInfo
{
uint16_t projectileAllowance;
uint8_t
remoteProjectileExchanges;
uint8_t remoteHealthExchanges;
};
struct RadarInfo
{
uint8_t availableDoubleVulnerablilityEffects;
bool activeDoubleVulnerabilityEffect;
};
struct GameData
{
GameType gameType;
GameStage gameStage;
uint16_t stageTimeRemaining;
uint64_t unixTime;
GameWinner gameWinner;
EventData eventData;
SupplierAction supplier;
DartInfo dartInfo;
AirSupportData airSupportData;
DartStationInfo dartStation;
GroundRobotPositions positions;
RadarMarkProgress
radarProgress;
SentryInfo sentry;
RadarInfo radar;
};
struct RobotData
{
RobotId robotId;
uint8_t robotLevel;
uint16_t previousHp;
uint16_t currentHp;
uint16_t maxHp;
RobotPower_t robotPower;
ArmorId damagedArmorId;
DamageType damageType;
float receivedDps;
ChassisData chassis;
TurretData turret;
RobotHpData allRobotHp;
uint16_t remainingCoins;
RobotBuffStatus robotBuffStatus;
RFIDActivationStatus_t rfidStatus;
uint32_t robotDataReceivedTimestamp;
RefereeWarningData refereeWarningData;
};
};
class Tx
{
public:
enum DeleteGraphicOperation
{
DELETE_GRAPHIC_NO_OP = 0,
DELETE_GRAPHIC_LAYER = 1,
DELETE_ALL = 2,
};
enum GraphicOperation
{
GRAPHIC_NO_OP = 0,
GRAPHIC_ADD = 1,
GRAPHIC_MODIFY = 2,
GRAPHIC_DELETE = 3,
};
enum class GraphicType : uint8_t
{
STRAIGHT_LINE = 0,
RECTANGLE = 1,
CIRCLE = 2,
ELLIPSE = 3,
ARC = 4,
FLOATING_NUM = 5,
INTEGER = 6,
CHARACTER = 7,
};
enum class GraphicColor : uint8_t
{
RED_AND_BLUE = 0,
YELLOW = 1,
GREEN = 2,
ORANGE = 3,
PURPLISH_RED = 4,
PINK = 5,
CYAN = 6,
BLACK = 7,
WHITE = 8,
};
struct InteractiveHeader
{
uint16_t dataCmdId;
uint16_t senderId;
uint16_t receiverId;
} modm_packed;
struct GraphicData
{
uint8_t name[3];
uint32_t operation : 3;
uint32_t type : 3;
uint32_t layer : 4;
uint32_t color : 4;
uint32_t startAngle : 9;
uint32_t endAngle : 9;
uint32_t lineWidth : 10;
uint32_t startX : 11;
uint32_t startY : 11;
union
{
struct
{
uint32_t radius : 10;
uint32_t endX : 11;
uint32_t endY : 11;
} modm_packed;
int32_t value : 32;
} modm_packed;
} modm_packed;
struct DeleteGraphicLayerMessage
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
uint8_t deleteOperation;
uint8_t layer;
uint16_t crc16;
} modm_packed;
struct Graphic1Message
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
GraphicData graphicData;
uint16_t crc16;
} modm_packed;
struct RobotToRobotMessage
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
uint8_t dataAndCRC16[115];
} modm_packed;
struct Graphic2Message
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
GraphicData graphicData[2];
uint16_t crc16;
} modm_packed;
struct Graphic5Message
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
GraphicData graphicData[5];
uint16_t crc16;
} modm_packed;
struct Graphic7Message
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
GraphicData graphicData[7];
uint16_t crc16;
} modm_packed;
struct GraphicCharacterMessage
{
DJISerial::FrameHeader frameHeader;
uint16_t cmdId;
InteractiveHeader interactiveHeader;
GraphicData graphicData;
char msg[30];
uint16_t crc16;
} modm_packed;
static constexpr uint32_t MAX_TRANSMIT_SPEED_BYTES_PER_S = 1000;
template <typename T>
static constexpr uint32_t getWaitTimeAfterGraphicSendMs(T *)
{
// Must be a valid graphic message type
static_assert(
std::is_same<T, DeleteGraphicLayerMessage>::value ||
std::is_same<T, Graphic1Message>::value ||
std::is_same<T, RobotToRobotMessage>::value ||
std::is_same<T, Graphic2Message>::value ||
std::is_same<T, Graphic5Message>::value ||
std::is_same<T, Graphic7Message>::value ||
std::is_same<T, GraphicCharacterMessage>::value,
"Invalid type, getWaitTimeAfterGraphicSendMs only takes in ref serial message "
"types.");
return sizeof(T) * 1'000 / MAX_TRANSMIT_SPEED_BYTES_PER_S;
}
};
};
inline RefSerialData::RobotId operator+(RefSerialData::RobotId id1, RefSerialData::RobotId id2)
{
return static_cast<RefSerialData::RobotId>(
static_cast<uint16_t>(id1) + static_cast<uint16_t>(id2));
}
inline RefSerialData::RobotId operator-(RefSerialData::RobotId id1, RefSerialData::RobotId id2)
{
return static_cast<RefSerialData::RobotId>(
static_cast<uint16_t>(id1) - static_cast<uint16_t>(id2));
}
} // namespace tap::communication::serial
#endif // TAPROOT_REF_SERIAL_DATA_HPP_