Commit 629a10fc authored by Ian McInerney's avatar Ian McInerney

Merge branch 'computation'

parents f58c756c f61021be
......@@ -26,8 +26,9 @@ PLATFORM ?= CF2
##### Sets the name of the stabilizer module to use.
SENSORS ?= stock
ESTIMATOR ?= complementary
CONTROLLER ?= pid
#CONTROLLER ?= lqr
COMPUTATION ?= localization
#CONTROLLER ?= pid
CONTROLLER ?= lqr
POWER_DISTRIBUTION ?= stock
......@@ -111,7 +112,7 @@ FREERTOS_OBJ = list.o tasks.o queue.o timers.o $(MEMMANG_OBJ)
# Crazyflie sources
VPATH += src/init src/hal/src src/modules/src src/utils/src src/drivers/src
VPATH += src/modules/src/controllers src/modules/src/estimators
VPATH += src/modules/src/controllers src/modules/src/estimators src/modules/src/computation
VPATH_CF1 += src/platform/cf1
VPATH_CF2 += src/platform/cf2
......@@ -152,7 +153,7 @@ PROJ_OBJ_CF2 += libdw1000.o libdw1000Spi.o
# Modules
PROJ_OBJ += system.o comm.o console.o pid.o crtpservice.o param.o mem.o
PROJ_OBJ += log.o worker.o trigger.o sitaw.o queuemonitor.o
PROJ_OBJ += log.o worker.o trigger.o sitaw.o queuemonitor.o msp.o
PROJ_OBJ_CF1 += sound_cf1.o
PROJ_OBJ_CF2 += platformservice.o sound_cf2.o extrx.o
......@@ -162,6 +163,7 @@ PROJ_OBJ += position_estimator_altitude.o position_controller_pid.o
PROJ_OBJ += estimator_$(ESTIMATOR).o controller_$(CONTROLLER).o
PROJ_OBJ += sensors_$(SENSORS).o power_distribution_$(POWER_DISTRIBUTION).o
PROJ_OBJ += controller_update.o
PROJ_OBJ += computation_CRTP.o computation_$(COMPUTATION).o
# Deck Core
PROJ_OBJ_CF2 += deck.o deck_info.o deck_drivers.o deck_test.o
......@@ -178,10 +180,21 @@ PROJ_OBJ_CF2 += rzr.o
PROJ_OBJ_CF2 += ledring12.o
PROJ_OBJ_CF2 += buzzdeck.o
PROJ_OBJ_CF2 += gtgps.o
PROJ_OBJ_CF2 += dwm1000.o
PROJ_OBJ_CF2 += cppmdeck.o
PROJ_OBJ_CF2 += locodeck.o
ifeq ($(LPS_TDMA_ENABLE), 1)
PROJ_OBJ_CF2 += lpsTwrTdmaTag.o
else
PROJ_OBJ_CF2 += lpsTwrTag.o
endif
ifeq ($(LPS_TDOA_ENABLE), 1)
PROJ_OBJ_CF2 += lpsTdoaTag.o
CFLAGS += -DLPS_TDOA_ENABLE
endif
#Deck tests
PROJ_OBJ_CF2 += exptest.o
#PROJ_OBJ_CF2 += exptest.o
#PROJ_OBJ_CF2 += bigquadtest.o
# Lateral position (Custom)
......@@ -220,6 +233,7 @@ GDB = $(CROSS_COMPILE)gdb
INCLUDES = -I$(FREERTOS)/include -I$(PORT) -Isrc
INCLUDES += -Isrc/config -Isrc/hal/interface -Isrc/modules/interface
INCLUDES += -Isrc/modules/interface/controllers -Isrc/modules/interface/estimators
INCLUDES += -Isrc/modules/interface/computation
INCLUDES += -Isrc/utils/interface -Isrc/drivers/interface -Isrc/platform
INCLUDES += -Ivendor/CMSIS/CMSIS/Include
......@@ -267,7 +281,7 @@ ifeq ($(USE_ESKYLINK), 1)
CFLAGS += -DUSE_ESKYLINK
endif
CFLAGS += -DBOARD_REV_$(REV) -DSENSORS_TYPE_$(SENSORS) -DESTIMATOR_TYPE_$(ESTIMATOR) -DCONTROLLER_TYPE_$(CONTROLLER) -DPOWER_DISTRIBUTION_TYPE_$(POWER_DISTRIBUTION)
CFLAGS += -DBOARD_REV_$(REV) -DSENSORS_TYPE_$(SENSORS) -DESTIMATOR_TYPE_$(ESTIMATOR) -DCONTROLLER_TYPE_$(CONTROLLER) -DPOWER_DISTRIBUTION_TYPE_$(POWER_DISTRIBUTION) -DCOMPUTATION_TYPE_$(COMPUTATION)
CFLAGS += $(PROCESSOR) $(INCLUDES) $(STFLAGS)
ifeq ($(PLATFORM), CF1)
......
/**
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* Crazyflie control firmware
*
* Copyright (C) 2016 Bitcraze AB
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* locodeck.h: Dwm1000 deck driver.
*/
#ifndef __LOCODECK_H__
#define __LOCODECK_H__
#include <stddef.h>
#include <stdint.h>
#include "libdw1000.h"
#include "stabilizer_types.h"
#define SPEED_OF_LIGHT 299792458.0
// Timestamp counter frequency
#define LOCODECK_TS_FREQ (499.2e6 * 128)
typedef enum uwbEvent_e {
eventTimeout,
eventPacketReceived,
eventPacketSent,
eventReceiveTimeout,
eventReceiveFailed,
} uwbEvent_t;
#define LOCODECK_NR_OF_ANCHORS 1
typedef uint64_t locoAddress_t;
typedef struct {
const uint64_t antennaDelay;
const int rangingFailedThreshold;
const locoAddress_t tagAddress;
const locoAddress_t anchorAddress[LOCODECK_NR_OF_ANCHORS];
point_t anchorPosition[LOCODECK_NR_OF_ANCHORS];
bool combinedAnchorPositionOk;
float distance[LOCODECK_NR_OF_ANCHORS];
float pressures[LOCODECK_NR_OF_ANCHORS];
int failedRanging[LOCODECK_NR_OF_ANCHORS];
volatile uint16_t rangingState;
} lpsAlgoOptions_t;
point_t* locodeckGetAnchorPosition(uint8_t anchor);
// Callback for one uwb algorithm
typedef struct uwbAlgorithm_s {
void (*init)(dwDevice_t *dev, lpsAlgoOptions_t* options);
uint32_t (*onEvent)(dwDevice_t *dev, uwbEvent_t event);
} uwbAlgorithm_t;
#include <FreeRTOS.h>
#define MAX_TIMEOUT portMAX_DELAY
// Send a short configuration packet to the LPS system
// Returns true if packet will be send, false instead
bool lpsSendLppShort(uint8_t destId, void* data, size_t length);
typedef struct {
uint8_t dest;
uint8_t length;
uint8_t data[30];
} lpsLppShortPacket_t;
// Poll if there is a LPS short configuration packet to send
// Return true if the packet data has been filled in shortPacket
// Return false if no packet to send
// Function to be used by the LPS algorithm
bool lpsGetLppShort(lpsLppShortPacket_t* shortPacket);
// Handle incoming short LPP packets from the UWB system
void lpsHandleLppShortPacket(uint8_t srcId, uint8_t *data, int length);
// LPP Packet types and format
#define LPP_HEADER_SHORT_PACKET 0xF0
#define LPP_SHORT_ANCHORPOS 0x01
struct lppShortAnchorPos_s {
float x;
float y;
float z;
} __attribute__((packed));
#endif // __LOCODECK_H__
#ifndef __LPS_TDOA_TAG_H__
#define __LPS_TDOA_TAG_H__
#include "locodeck.h"
#include "libdw1000.h"
#include "mac.h"
extern uwbAlgorithm_t uwbTdoaTagAlgorithm;
typedef struct rangePacket_s {
uint8_t type;
uint8_t txMaster[5];
uint8_t timestamps[LOCODECK_NR_OF_ANCHORS][5];
} __attribute__((packed)) rangePacket_t;
#endif // __LPS_TDOA_TAG_H__
#ifndef __LPS_TWR_TAG_H__
#define __LPS_TWR_TAG_H__
#include "locodeck.h"
#include "libdw1000.h"
#include "mac.h"
#define LPS_TWR_POLL 0x01 // Poll is initiated by the tag
#define LPS_TWR_ANSWER 0x02
#define LPS_TWR_FINAL 0x03
#define LPS_TWR_REPORT 0x04 // Report contains all measurement from the anchor
#define LPS_TWR_LPP_SHORT 0xF0
#define LPS_TWR_TYPE 0
#define LPS_TWR_SEQ 1
// LPP payload can be in the ANSWER packet
#define LPS_TWR_LPP_HEADER 2
#define LPS_TWR_LPP_TYPE 3
#define LPS_TWR_LPP_PAYLOAD 4
#define LPS_TWR_SEND_LPP_PAYLOAD 1
extern uwbAlgorithm_t uwbTwrTagAlgorithm;
typedef struct {
uint8_t pollRx[5];
uint8_t answerTx[5];
uint8_t finalRx[5];
float pressure;
float temperature;
float asl;
uint8_t pressure_ok;
} __attribute__((packed)) lpsTwrTagReportPayload_t;
#endif // __LPS_TWR_TAG_H__
......@@ -3,6 +3,7 @@
#include <stdint.h>
#include "locodeck.h"
// Packet format with compressed PAN and 64Bit addresses
// Maximum 64 bytes payload
......@@ -24,8 +25,8 @@ typedef struct packet_s {
uint8_t seq;
uint16_t pan;
uint8_t destAddress[8];
uint8_t sourceAddress[8];
locoAddress_t destAddress;
locoAddress_t sourceAddress;
uint8_t payload[64];
} __attribute__((packed)) packet_t;
......
......@@ -35,15 +35,42 @@
#include "deck.h"
#include "extrx.h"
#include "pm.h"
#include "uart1.h"
#include "msp.h"
#include "FreeRTOS.h"
#include "task.h"
#define BIGQUAD_BAT_VOLT_PIN DECK_GPIO_MISO
#define BIGQUAD_BAT_VOLT_MULT 7.8f
#define BIGQUAD_BAT_CURR_PIN DECK_GPIO_SCK
#define BIGQUAD_BAT_AMP_PER_VOLT 1.0f
#ifdef ENABLE_BQ_DECK
//Hardware configuration
static bool isInit;
#ifdef BQ_DECK_ENABLE_OSD
static MspObject s_MspObject;
static void osdTask(void *param)
{
while(1)
{
char ch;
uart1Getchar(&ch);
mspProcessByte(&s_MspObject, (uint8_t)ch);
}
}
static void osdResponseCallback(uint8_t* pBuffer, uint32_t bufferLen)
{
uart1SendData(bufferLen, pBuffer);
}
#endif // BQ_DECK_ENABLE_OSD
static void bigquadInit(DeckInfo *info)
{
if(isInit)
......@@ -57,6 +84,13 @@ static void bigquadInit(DeckInfo *info)
pmEnableExtBatteryCurrMeasuring(BIGQUAD_BAT_CURR_PIN, BIGQUAD_BAT_AMP_PER_VOLT);
#endif
#ifdef BQ_DECK_ENABLE_OSD
uart1Init(115200);
mspInit(&s_MspObject, osdResponseCallback);
xTaskCreate(osdTask, "BQ_OSDTASK",
configMINIMAL_STACK_SIZE, NULL, /*priority*/1, NULL);
#endif
isInit = true;
}
......@@ -83,6 +117,5 @@ static const DeckDriver bigquad_deck = {
.test = bigquadTest,
};
#ifdef ENABLE_BQ_DECK
DECK_DRIVER(bigquad_deck);
#endif
#endif // ENABLE_BQ_DECK
......@@ -125,19 +125,19 @@ static const uint8_t blueRing[][3] = {{64, 64, 255}, {32,32,64}, {8,8,16},
BLACK, BLACK, BLACK,
BLACK, BLACK, BLACK,
};
/*
static const uint8_t greenRing[][3] = {{64, 255, 64}, {32,64,32}, {8,16,8},
BLACK, BLACK, BLACK,
BLACK, BLACK, BLACK,
BLACK, BLACK, BLACK,
};
static const uint8_t redRing[][3] = {{64, 0, 0}, {16,0,0}, {8,0,0},
{4,0,0}, {2,0,0}, {1,0,0},
BLACK, BLACK, BLACK,
BLACK, BLACK, BLACK,
};
*/
//static const uint8_t greenRing[][3] = {{64, 255, 64}, {32,64,32}, {8,16,8},
// BLACK, BLACK, BLACK,
// BLACK, BLACK, BLACK,
// BLACK, BLACK, BLACK,
// };
//
//static const uint8_t redRing[][3] = {{64, 0, 0}, {16,0,0}, {8,0,0},
// {4,0,0}, {2,0,0}, {1,0,0},
// BLACK, BLACK, BLACK,
// BLACK, BLACK, BLACK,
// };
static void whiteSpinEffect(uint8_t buffer[][3], bool reset)
{
int i;
......@@ -387,7 +387,7 @@ static float gravityLightCalculateAngle(float pitch, float roll) {
if (roll != 0) {
angle = atanf(pitch / roll) + (float) M_PI_2;
if (roll < 0.0) {
if (roll < 0.0f) {
angle += (float) M_PI;
}
}
......
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* LPS node firmware.
*
* Copyright 2016, Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lpsTdoaTag.c 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 lpsTdoaTag.c. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "log.h"
#include "lpsTdoaTag.h"
#include "stabilizer_types.h"
#include "cfassert.h"
#ifdef ESTIMATOR_TYPE_kalman
#include "estimator_kalman.h"
#endif // ESTIMATOR_TYPE_kalman
static lpsAlgoOptions_t* options;
static float uwbTdoaDistDiff[LOCODECK_NR_OF_ANCHORS];
static uint8_t previousAnchor;
static rangePacket_t rxPacketBuffer[LOCODECK_NR_OF_ANCHORS];
static dwTime_t arrivals[LOCODECK_NR_OF_ANCHORS];
static double frameTime_in_cl_A[LOCODECK_NR_OF_ANCHORS];
static double clockCorrection_T_To_A[LOCODECK_NR_OF_ANCHORS];
#define MEASUREMENT_NOISE_STD 0.15f
// The maximum diff in distances that we consider to be valid
// Used to sanity check results and remove results that are wrong due to packet loss
#define MAX_DISTANCE_DIFF (5.0f)
static uint32_t statsReceivedPackets = 0;
static uint32_t statsAcceptedAnchorDataPackets = 0;
static uint32_t statsAcceptedPackets = 0;
static uint64_t timestampToUint64(const uint8_t *ts) {
dwTime_t timestamp = {.full = 0};
memcpy(timestamp.raw, ts, sizeof(timestamp.raw));
return timestamp.full;
}
static uint64_t truncateToTimeStamp(uint64_t fullTimeStamp) {
return fullTimeStamp & 0x00FFFFFFFFFFul;
}
#ifdef ESTIMATOR_TYPE_kalman
static void enqueueTDOA(uint8_t anchor1, uint8_t anchor2, double distanceDiff) {
tdoaMeasurement_t tdoa = {
.stdDev = MEASUREMENT_NOISE_STD,
.distanceDiff = distanceDiff,
.anchorPosition[0] = options->anchorPosition[anchor1],
.anchorPosition[1] = options->anchorPosition[anchor2]
};
stateEstimatorEnqueueTDOA(&tdoa);
}
#endif
static double calcClockCorrection(const double frameTime, const double previuosFrameTime) {
double clockCorrection = 1.0;
if (frameTime != 0.0) {
clockCorrection = previuosFrameTime / frameTime;
}
return clockCorrection;
}
// The default receive time in the anchors for messages from other anchors is 0
// and is overwritten with the actual receive time when a packet arrives.
// That is, if no message was received the rx time will be 0.
static bool isValidRxTime(const int64_t anchorRxTime) {
return anchorRxTime != 0;
}
// A note on variable names. They might seem a bit verbose but express quite a lot of information
// We have three actors: Reference anchor (Ar), Anchor n (An) and the deck on the CF called Tag (T)
// rxAr_by_An_in_cl_An should be interpreted as "The time when packet was received from the Referecne Anchor by Anchor N expressed in the clock of Anchor N"
static void rxcallback(dwDevice_t *dev) {
statsReceivedPackets++;
int dataLength = dwGetDataLength(dev);
packet_t rxPacket;
dwGetData(dev, (uint8_t*)&rxPacket, dataLength);
dwTime_t arrival = {.full = 0};
dwGetReceiveTimestamp(dev, &arrival);
const uint8_t anchor = rxPacket.sourceAddress & 0xff;
if (anchor < LOCODECK_NR_OF_ANCHORS) {
const rangePacket_t* packet = (rangePacket_t*)rxPacket.payload;
const int64_t previous_rxAn_by_T_in_cl_T = arrivals[anchor].full;
const int64_t rxAn_by_T_in_cl_T = arrival.full;
const int64_t previous_txAn_in_cl_An = timestampToUint64(rxPacketBuffer[anchor].timestamps[anchor]);
const int64_t txAn_in_cl_An = timestampToUint64(packet->timestamps[anchor]);
if (anchor != previousAnchor) {
const int64_t previuos_rxAr_by_An_in_cl_An = timestampToUint64(rxPacketBuffer[anchor].timestamps[previousAnchor]);
const int64_t rxAr_by_An_in_cl_An = timestampToUint64(packet->timestamps[previousAnchor]);
const int64_t rxAn_by_Ar_in_cl_Ar = timestampToUint64(rxPacketBuffer[previousAnchor].timestamps[anchor]);
if (isValidRxTime(previuos_rxAr_by_An_in_cl_An) && isValidRxTime(rxAr_by_An_in_cl_An) && isValidRxTime(rxAn_by_Ar_in_cl_Ar)) {
statsAcceptedAnchorDataPackets++;
// Caclculate clock correction from anchor to reference anchor
const double frameTime_in_cl_An = truncateToTimeStamp(rxAr_by_An_in_cl_An - previuos_rxAr_by_An_in_cl_An);
const double clockCorrection_An_To_Ar = calcClockCorrection(frameTime_in_cl_An, frameTime_in_cl_A[previousAnchor]);
const int64_t rxAr_by_T_in_cl_T = arrivals[previousAnchor].full;
const int64_t txAr_in_cl_Ar = timestampToUint64(rxPacketBuffer[previousAnchor].timestamps[previousAnchor]);
// Calculate distance diff
const int64_t tof_Ar_to_An_in_cl_Ar = (((truncateToTimeStamp(rxAr_by_An_in_cl_An - previous_txAn_in_cl_An) * clockCorrection_An_To_Ar) - truncateToTimeStamp(txAr_in_cl_Ar - rxAn_by_Ar_in_cl_Ar))) / 2.0;
const int64_t delta_txAr_to_txAn_in_cl_Ar = (tof_Ar_to_An_in_cl_Ar + truncateToTimeStamp(txAn_in_cl_An - rxAr_by_An_in_cl_An) * clockCorrection_An_To_Ar);
const int64_t timeDiffOfArrival_in_cl_Ar = truncateToTimeStamp(rxAn_by_T_in_cl_T - rxAr_by_T_in_cl_T) * clockCorrection_T_To_A[previousAnchor] - delta_txAr_to_txAn_in_cl_Ar;
const float tdoaDistDiff = SPEED_OF_LIGHT * timeDiffOfArrival_in_cl_Ar / LOCODECK_TS_FREQ;
// Sanity check distances in case of missed packages
if (tdoaDistDiff > -MAX_DISTANCE_DIFF && tdoaDistDiff < MAX_DISTANCE_DIFF) {
uwbTdoaDistDiff[anchor] = tdoaDistDiff;
#ifdef ESTIMATOR_TYPE_kalman
enqueueTDOA(previousAnchor, anchor, tdoaDistDiff);
#endif
statsAcceptedPackets++;
}
}
}
// Calculate clock correction for tag to anchor
const double frameTime_in_T = truncateToTimeStamp(rxAn_by_T_in_cl_T - previous_rxAn_by_T_in_cl_T);
frameTime_in_cl_A[anchor] = truncateToTimeStamp(txAn_in_cl_An - previous_txAn_in_cl_An);
clockCorrection_T_To_A[anchor] = calcClockCorrection(frameTime_in_T, frameTime_in_cl_A[anchor]);
arrivals[anchor].full = arrival.full;
memcpy(&rxPacketBuffer[anchor], rxPacket.payload, sizeof(rangePacket_t));
previousAnchor = anchor;
}
}
static void setRadioInReceiveMode(dwDevice_t *dev) {
dwNewReceive(dev);
dwSetDefaults(dev);
dwStartReceive(dev);
}
static uint32_t onEvent(dwDevice_t *dev, uwbEvent_t event) {
switch(event) {
case eventPacketReceived:
rxcallback(dev);
setRadioInReceiveMode(dev);
break;
case eventTimeout:
setRadioInReceiveMode(dev);
break;
case eventReceiveTimeout:
setRadioInReceiveMode(dev);
break;
default:
ASSERT_FAILED();
}
return MAX_TIMEOUT;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
static void Initialize(dwDevice_t *dev, lpsAlgoOptions_t* algoOptions) {
options = algoOptions;
// Reset module state. Needed by unit tests
memset(rxPacketBuffer, 0, sizeof(rxPacketBuffer));
memset(arrivals, 0, sizeof(arrivals));
memset(frameTime_in_cl_A, 0, sizeof(frameTime_in_cl_A));
memset(clockCorrection_T_To_A, 0, sizeof(clockCorrection_T_To_A));
previousAnchor = 0;
memset(uwbTdoaDistDiff, 0, sizeof(uwbTdoaDistDiff));
statsReceivedPackets = 0;
statsAcceptedAnchorDataPackets = 0;
statsAcceptedPackets = 0;
}
#pragma GCC diagnostic pop
uwbAlgorithm_t uwbTdoaTagAlgorithm = {
.init = Initialize,
.onEvent = onEvent,
};
LOG_GROUP_START(tdoa)
LOG_ADD(LOG_FLOAT, d0, &uwbTdoaDistDiff[0])
LOG_ADD(LOG_FLOAT, d1, &uwbTdoaDistDiff[1])
LOG_ADD(LOG_FLOAT, d2, &uwbTdoaDistDiff[2])
LOG_ADD(LOG_FLOAT, d3, &uwbTdoaDistDiff[3])
LOG_ADD(LOG_FLOAT, d4, &uwbTdoaDistDiff[4])
LOG_ADD(LOG_FLOAT, d5, &uwbTdoaDistDiff[5])
LOG_ADD(LOG_FLOAT, d6, &uwbTdoaDistDiff[6])
LOG_ADD(LOG_FLOAT, d7, &uwbTdoaDistDiff[7])
LOG_ADD(LOG_UINT32, rxCnt, &statsReceivedPackets)
LOG_ADD(LOG_UINT32, anCnt, &statsAcceptedAnchorDataPackets)
LOG_ADD(LOG_UINT32, okCnt, &statsAcceptedPackets)
LOG_GROUP_STOP(tdoa)
/*
* || ____ _ __
* +------+ / __ )(_) /_______________ _____ ___
* | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \
* +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
* || || /_____/_/\__/\___/_/ \__,_/ /___/\___/
*
* LPS node firmware.
*
* Copyright 2016, Bitcraze AB
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Foobar 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/* uwb_twr_anchor.c: Uwb two way ranging tag with TDMA implementation */
#include "locodeck.h"