Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bridge/bridge_ios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ static void carStateToBridge(const CarState& cs, BridgeCarState* out) {
out->tpmsTempFR = cs.tpmsTempFR;
out->tpmsTempRL = cs.tpmsTempRL;
out->tpmsTempRR = cs.tpmsTempRR;
out->tpmsBattFL = cs.tpmsBattFL;
out->tpmsBattFR = cs.tpmsBattFR;
out->tpmsBattRL = cs.tpmsBattRL;
out->tpmsBattRR = cs.tpmsBattRR;
}

static std::atomic<bool> receiveLoopRunning{false};
Expand Down
6 changes: 5 additions & 1 deletion bridge/bridge_ios.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ typedef struct {
double experimentalMode;
double changingLane;

// TPMS: pressure (bar, -1 = none) and temperature (degC, -100 = none) per wheel.
// TPMS: pressure (bar, -1 = none), temperature (degC, -100 = none) and sensor battery (V, -1 = none) per wheel.
double tpmsPressureFL;
double tpmsPressureFR;
double tpmsPressureRL;
Expand All @@ -60,6 +60,10 @@ typedef struct {
double tpmsTempFR;
double tpmsTempRL;
double tpmsTempRR;
double tpmsBattFL;
double tpmsBattFR;
double tpmsBattRL;
double tpmsBattRR;
} BridgeCarState;

// Context
Expand Down
16 changes: 12 additions & 4 deletions bridge/car/car_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ struct CarState {
double experimentalMode = 0;
double changingLane = 0;

// Tyre pressure (bar) and temperature (degC) per wheel from VCSEC_TPMSData;
// pressure -1 = no reading, temperature -100 = no reading.
// Tyre pressure (bar), temperature (degC) and sensor battery (V) per wheel from
// VCSEC_TPMSData; pressure -1, temperature -100 and battery -1 = no reading.
double tpmsPressureFL = -1;
double tpmsPressureFR = -1;
double tpmsPressureRL = -1;
Expand All @@ -56,6 +56,10 @@ struct CarState {
double tpmsTempFR = -100;
double tpmsTempRL = -100;
double tpmsTempRR = -100;
double tpmsBattFL = -1;
double tpmsBattFR = -1;
double tpmsBattRL = -1;
double tpmsBattRR = -1;

// Vehicle VIN, empty until fully assembled by the mapper.
static constexpr size_t VIN_LENGTH = 17;
Expand All @@ -64,7 +68,7 @@ struct CarState {
static constexpr size_t VIN_DOUBLE_COUNT = 3;
static constexpr size_t VIN_OFFSET = 36;
static constexpr size_t TPMS_OFFSET = VIN_OFFSET + VIN_DOUBLE_COUNT;
static constexpr size_t TPMS_COUNT = 8;
static constexpr size_t TPMS_COUNT = 12;
static constexpr size_t FIELD_COUNT = TPMS_OFFSET + TPMS_COUNT;

void toArray(double* out) const {
Expand Down Expand Up @@ -117,7 +121,7 @@ struct CarState {
std::memcpy(padded, vin, VIN_LENGTH);
std::memcpy(out + VIN_OFFSET, padded, sizeof(padded));

// TPMS (after VIN): pressures FL FR RL RR, then temperatures FL FR RL RR.
// TPMS (after VIN): pressures FL FR RL RR, temperatures FL FR RL RR, sensor batteries FL FR RL RR.
out[TPMS_OFFSET + 0] = tpmsPressureFL;
out[TPMS_OFFSET + 1] = tpmsPressureFR;
out[TPMS_OFFSET + 2] = tpmsPressureRL;
Expand All @@ -126,5 +130,9 @@ struct CarState {
out[TPMS_OFFSET + 5] = tpmsTempFR;
out[TPMS_OFFSET + 6] = tpmsTempRL;
out[TPMS_OFFSET + 7] = tpmsTempRR;
out[TPMS_OFFSET + 8] = tpmsBattFL;
out[TPMS_OFFSET + 9] = tpmsBattFR;
out[TPMS_OFFSET + 10] = tpmsBattRL;
out[TPMS_OFFSET + 11] = tpmsBattRR;
}
};
5 changes: 4 additions & 1 deletion bridge/car/cars/tesla.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class TeslaDashKitMapper : public CarStateMapper {
updateVehicleBus(cp, cs);
vin_.update(cp, cs);
// TPMS: pressures come from mux 5 (all four wheels, 0.025 bar resolution);
// temperatures from muxes 0-3 (one sensor each). Their per-sensor pressure is
// temperatures and sensor battery voltages from muxes 0-3 (one sensor each). Their per-sensor pressure is
// coarser (0.05 bar) and would alternate with mux 5, so it is not used.
// Fields keep their last value until a frame carries that wheel again.
// getRaw fails until a frame has been seen; get() would read 0 and look like mux 0.
Expand All @@ -205,6 +205,9 @@ class TeslaDashKitMapper : public CarStateMapper {
double* tempOfMux[4] = {&cs.tpmsTempRR, &cs.tpmsTempRL, &cs.tpmsTempFR, &cs.tpmsTempFL};
double t = cp.get(1, "VCSEC_TPMSData", "VCSEC_TPMSTemperature" + std::to_string(tpmsIndex));
if (t < 214.5) *tempOfMux[tpmsIndex] = t;
double* battOfMux[4] = {&cs.tpmsBattRR, &cs.tpmsBattRL, &cs.tpmsBattFR, &cs.tpmsBattFL};
double v = cp.get(1, "VCSEC_TPMSData", "VCSEC_TPMSBatVoltage" + std::to_string(tpmsIndex));
if (v < 4.045) *battOfMux[tpmsIndex] = v; // raw 0xFF (4.05 V) = not available
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions dash-apps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ Values not received yet are `0` / `false`. For speed limit, stop line and energy
| `maxRegenPower`, `maxDischargePower` | kW | current limits |
| `packTMin`, `packTMax` | °C, or °F when `isImperial` | |

**Tyres** (Tesla via DashKit)

| key | type | meaning |
|---|---|---|
| `tpmsPressureFL`, `tpmsPressureFR`, `tpmsPressureRL`, `tpmsPressureRR` | bar | -1 = no reading |
| `tpmsTempFL`, `tpmsTempFR`, `tpmsTempRL`, `tpmsTempRR` | °C | -100 = no reading |
| `tpmsBattFL`, `tpmsBattFR`, `tpmsBattRL`, `tpmsBattRR` | V | sensor battery, -1 = no reading |

The app's CarState also has climate fields and the VIN; dash apps don't receive those yet.

## Rive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ data class CarState(

val changingLane: Boolean = false,

// TPMS: pressure (bar, -1 = none) and temperature (degC, -100 = none) per wheel.
// TPMS: pressure (bar, -1 = none), temperature (degC, -100 = none) and sensor battery (V, -1 = none) per wheel.
val tpmsPressureFL: Float = -1f,
val tpmsPressureFR: Float = -1f,
val tpmsPressureRL: Float = -1f,
Expand All @@ -52,6 +52,10 @@ data class CarState(
val tpmsTempFR: Float = -100f,
val tpmsTempRL: Float = -100f,
val tpmsTempRR: Float = -100f,
val tpmsBattFL: Float = -1f,
val tpmsBattFR: Float = -1f,
val tpmsBattRL: Float = -1f,
val tpmsBattRR: Float = -1f,

// Empty until fully assembled from the CAN stream by the native mapper.
val vin: String = ""
Expand All @@ -66,7 +70,7 @@ data class CarState(
)

companion object {
const val FIELD_COUNT = 47
const val FIELD_COUNT = 51
private const val KM_TO_MILES = 0.621371f

private val MILES_COUNTRIES = setOf("US", "GB", "MM", "LR")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ fun DashState.dashValues(systemDarkMode: Boolean? = null): Map<String, Any> {
"maxDischargePower" to c.maxDischargePower,
"packTMin" to c.packTMin,
"packTMax" to c.packTMax,
"tpmsPressureFL" to c.tpmsPressureFL,
"tpmsPressureFR" to c.tpmsPressureFR,
"tpmsPressureRL" to c.tpmsPressureRL,
"tpmsPressureRR" to c.tpmsPressureRR,
"tpmsTempFL" to c.tpmsTempFL,
"tpmsTempFR" to c.tpmsTempFR,
"tpmsTempRL" to c.tpmsTempRL,
"tpmsTempRR" to c.tpmsTempRR,
"tpmsBattFL" to c.tpmsBattFL,
"tpmsBattFR" to c.tpmsBattFR,
"tpmsBattRL" to c.tpmsBattRL,
"tpmsBattRR" to c.tpmsBattRR,
// Rive numbers are 32-bit floats, too coarse for epoch milliseconds.
"currentTime" to secondsSinceLocalMidnight(currentTime),
"phoneBattery" to phoneBattery.toFloat(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ class CarStateBridge(
@Volatile private var renderQuality: Int = 3
@Volatile private var darkModeBackgroundGray: Int = 0
@Volatile private var changingLane: Boolean = false
@Volatile private var tpmsPressureFL: Float = -1f
@Volatile private var tpmsPressureFR: Float = -1f
@Volatile private var tpmsPressureRL: Float = -1f
@Volatile private var tpmsPressureRR: Float = -1f
@Volatile private var tpmsTempFL: Float = -100f
@Volatile private var tpmsTempFR: Float = -100f
@Volatile private var tpmsTempRL: Float = -100f
@Volatile private var tpmsTempRR: Float = -100f
@Volatile private var tpmsBattFL: Float = -1f
@Volatile private var tpmsBattFR: Float = -1f
@Volatile private var tpmsBattRL: Float = -1f
@Volatile private var tpmsBattRR: Float = -1f
@Volatile private var speedCameraDistance: Int = -1
@Volatile private var dataSourceType: String = ""

Expand Down Expand Up @@ -82,6 +94,18 @@ class CarStateBridge(
experimentalMode = state.experimentalMode
madsActive = state.madsActive
changingLane = state.changingLane
tpmsPressureFL = state.tpmsPressureFL
tpmsPressureFR = state.tpmsPressureFR
tpmsPressureRL = state.tpmsPressureRL
tpmsPressureRR = state.tpmsPressureRR
tpmsTempFL = state.tpmsTempFL
tpmsTempFR = state.tpmsTempFR
tpmsTempRL = state.tpmsTempRL
tpmsTempRR = state.tpmsTempRR
tpmsBattFL = state.tpmsBattFL
tpmsBattFR = state.tpmsBattFR
tpmsBattRL = state.tpmsBattRL
tpmsBattRR = state.tpmsBattRR
}

@JavascriptInterface fun getEgoSteeringAngle(): Float = egoSteeringAngle
Expand Down Expand Up @@ -122,6 +146,18 @@ class CarStateBridge(
@JavascriptInterface fun getRenderQuality(): Int = renderQuality
@JavascriptInterface fun getDarkModeBackgroundGray(): Int = darkModeBackgroundGray
@JavascriptInterface fun isChangingLane(): Boolean = changingLane
@JavascriptInterface fun getTpmsPressureFL(): Float = tpmsPressureFL
@JavascriptInterface fun getTpmsPressureFR(): Float = tpmsPressureFR
@JavascriptInterface fun getTpmsPressureRL(): Float = tpmsPressureRL
@JavascriptInterface fun getTpmsPressureRR(): Float = tpmsPressureRR
@JavascriptInterface fun getTpmsTempFL(): Float = tpmsTempFL
@JavascriptInterface fun getTpmsTempFR(): Float = tpmsTempFR
@JavascriptInterface fun getTpmsTempRL(): Float = tpmsTempRL
@JavascriptInterface fun getTpmsTempRR(): Float = tpmsTempRR
@JavascriptInterface fun getTpmsBattFL(): Float = tpmsBattFL
@JavascriptInterface fun getTpmsBattFR(): Float = tpmsBattFR
@JavascriptInterface fun getTpmsBattRL(): Float = tpmsBattRL
@JavascriptInterface fun getTpmsBattRR(): Float = tpmsBattRR
@JavascriptInterface fun getSpeedCameraDistance(): Int = speedCameraDistance

fun updateSpeedCameraDistance(distanceMeters: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,19 @@ class CanFrameDecoder(
hvacKeepClimateOn = values[34].toFloat(),
powerLevel = values[35].toFloat(),
vin = decodeVin(values, offset = 36),
// TPMS after VIN (see CarState::TPMS_OFFSET): pressures FL FR RL RR, temperatures FL FR RL RR.
// TPMS after VIN (see CarState::TPMS_OFFSET): pressures, temperatures, sensor batteries; FL FR RL RR each.
tpmsPressureFL = values[39].toFloat(),
tpmsPressureFR = values[40].toFloat(),
tpmsPressureRL = values[41].toFloat(),
tpmsPressureRR = values[42].toFloat(),
tpmsTempFL = values[43].toFloat(),
tpmsTempFR = values[44].toFloat(),
tpmsTempRL = values[45].toFloat(),
tpmsTempRR = values[46].toFloat()
tpmsTempRR = values[46].toFloat(),
tpmsBattFL = values[47].toFloat(),
tpmsBattFR = values[48].toFloat(),
tpmsBattRL = values[49].toFloat(),
tpmsBattRR = values[50].toFloat()
)
}

Expand Down
2 changes: 1 addition & 1 deletion dashpilot-ios/dashpilot/JS/CarStateBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ extension DashState {
let cs = carState
let ds = displaySettings
let source = dataSourceType.map { "\"\($0.rawValue)\"" } ?? "null"
return "{\"egoSteeringAngle\":\(cs.egoSteeringAngle),\"egoSpeed\":\(cs.egoSpeed),\"leftBlinker\":\(cs.leftBlinker),\"rightBlinker\":\(cs.rightBlinker),\"gear\":\(cs.gear),\"adasOn\":\(cs.adasOn),\"leftBlindSpot\":\(cs.leftBlindSpot),\"rightBlindSpot\":\(cs.rightBlindSpot),\"fusedSpeedLimit\":\(cs.fusedSpeedLimit),\"stopLineDist\":\(cs.stopLineDist),\"trafficLightColor\":\(cs.trafficLightColor),\"anyDoorOpen\":\(cs.anyDoorOpen),\"buckleStatus\":\(cs.buckleStatus),\"accSetSpeed\":\(cs.accSetSpeed),\"fullPackEnergy\":\(cs.fullPackEnergy),\"nominalEnergyRemaining\":\(cs.nominalEnergyRemaining),\"energyBuffer\":\(cs.energyBuffer),\"maxRegenPower\":\(cs.maxRegenPower),\"maxDischargePower\":\(cs.maxDischargePower),\"packVoltage\":\(cs.packVoltage),\"packCurrent\":\(cs.packCurrent),\"powerLevel\":\(cs.powerLevel),\"packTMin\":\(cs.packTMin),\"packTMax\":\(cs.packTMax),\"odometer\":\(cs.odometer),\"madsActive\":\(cs.madsActive),\"selfdriveActive\":\(cs.selfdriveActive),\"experimentalMode\":\(cs.experimentalMode),\"changingLane\":\(cs.changingLane),\"phoneBattery\":\(phoneBattery),\"currentTime\":\(currentTime),\"dataSourceType\":\(source),\"showPhoneBattery\":\(ds.showPhoneBattery),\"showCarBattery\":\(ds.showCarBattery),\"showOdometer\":\(ds.showOdometer),\"isImperial\":\(ds.useImperial),\"darkMode\":\(ds.darkMode),\"alwaysOnBlindSpotMonitor\":\(ds.alwaysOnBlindSpotMonitor),\"renderQuality\":\(ds.renderQuality),\"darkModeBackgroundGray\":\(ds.darkModeBackgroundGray)}"
return "{\"egoSteeringAngle\":\(cs.egoSteeringAngle),\"egoSpeed\":\(cs.egoSpeed),\"leftBlinker\":\(cs.leftBlinker),\"rightBlinker\":\(cs.rightBlinker),\"gear\":\(cs.gear),\"adasOn\":\(cs.adasOn),\"leftBlindSpot\":\(cs.leftBlindSpot),\"rightBlindSpot\":\(cs.rightBlindSpot),\"fusedSpeedLimit\":\(cs.fusedSpeedLimit),\"stopLineDist\":\(cs.stopLineDist),\"trafficLightColor\":\(cs.trafficLightColor),\"anyDoorOpen\":\(cs.anyDoorOpen),\"buckleStatus\":\(cs.buckleStatus),\"accSetSpeed\":\(cs.accSetSpeed),\"fullPackEnergy\":\(cs.fullPackEnergy),\"nominalEnergyRemaining\":\(cs.nominalEnergyRemaining),\"energyBuffer\":\(cs.energyBuffer),\"maxRegenPower\":\(cs.maxRegenPower),\"maxDischargePower\":\(cs.maxDischargePower),\"packVoltage\":\(cs.packVoltage),\"packCurrent\":\(cs.packCurrent),\"powerLevel\":\(cs.powerLevel),\"packTMin\":\(cs.packTMin),\"packTMax\":\(cs.packTMax),\"odometer\":\(cs.odometer),\"madsActive\":\(cs.madsActive),\"selfdriveActive\":\(cs.selfdriveActive),\"experimentalMode\":\(cs.experimentalMode),\"changingLane\":\(cs.changingLane),\"tpmsPressureFL\":\(cs.tpmsPressureFL),\"tpmsPressureFR\":\(cs.tpmsPressureFR),\"tpmsPressureRL\":\(cs.tpmsPressureRL),\"tpmsPressureRR\":\(cs.tpmsPressureRR),\"tpmsTempFL\":\(cs.tpmsTempFL),\"tpmsTempFR\":\(cs.tpmsTempFR),\"tpmsTempRL\":\(cs.tpmsTempRL),\"tpmsTempRR\":\(cs.tpmsTempRR),\"tpmsBattFL\":\(cs.tpmsBattFL),\"tpmsBattFR\":\(cs.tpmsBattFR),\"tpmsBattRL\":\(cs.tpmsBattRL),\"tpmsBattRR\":\(cs.tpmsBattRR),\"phoneBattery\":\(phoneBattery),\"currentTime\":\(currentTime),\"dataSourceType\":\(source),\"showPhoneBattery\":\(ds.showPhoneBattery),\"showCarBattery\":\(ds.showCarBattery),\"showOdometer\":\(ds.showOdometer),\"isImperial\":\(ds.useImperial),\"darkMode\":\(ds.darkMode),\"alwaysOnBlindSpotMonitor\":\(ds.alwaysOnBlindSpotMonitor),\"renderQuality\":\(ds.renderQuality),\"darkModeBackgroundGray\":\(ds.darkModeBackgroundGray)}"
}
}
10 changes: 9 additions & 1 deletion dashpilot-ios/dashpilot/Models/CarState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct CarState: Codable {
var experimentalMode: Bool = false
var changingLane: Bool = false

// Tyre pressure (bar, -1 = none) and temperature (degC, -100 = none) per wheel.
// Tyre pressure (bar, -1 = none), temperature (degC, -100 = none) and sensor battery (V, -1 = none) per wheel.
var tpmsPressureFL: Float = -1
var tpmsPressureFR: Float = -1
var tpmsPressureRL: Float = -1
Expand All @@ -52,6 +52,10 @@ struct CarState: Codable {
var tpmsTempFR: Float = -100
var tpmsTempRL: Float = -100
var tpmsTempRR: Float = -100
var tpmsBattFL: Float = -1
var tpmsBattFR: Float = -1
var tpmsBattRL: Float = -1
var tpmsBattRR: Float = -1

init() {}

Expand Down Expand Up @@ -100,6 +104,10 @@ struct CarState: Codable {
tpmsTempFR = Float(bridge.tpmsTempFR)
tpmsTempRL = Float(bridge.tpmsTempRL)
tpmsTempRR = Float(bridge.tpmsTempRR)
tpmsBattFL = Float(bridge.tpmsBattFL)
tpmsBattFR = Float(bridge.tpmsBattFR)
tpmsBattRL = Float(bridge.tpmsBattRL)
tpmsBattRR = Float(bridge.tpmsBattRR)
}

private static let kmToMiles: Float = 0.621371
Expand Down
12 changes: 12 additions & 0 deletions dashpilot-ios/dashpilot/Models/DashValues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ extension DashState {
("maxDischargePower", .number(c.maxDischargePower)),
("packTMin", .number(c.packTMin)),
("packTMax", .number(c.packTMax)),
("tpmsPressureFL", .number(c.tpmsPressureFL)),
("tpmsPressureFR", .number(c.tpmsPressureFR)),
("tpmsPressureRL", .number(c.tpmsPressureRL)),
("tpmsPressureRR", .number(c.tpmsPressureRR)),
("tpmsTempFL", .number(c.tpmsTempFL)),
("tpmsTempFR", .number(c.tpmsTempFR)),
("tpmsTempRL", .number(c.tpmsTempRL)),
("tpmsTempRR", .number(c.tpmsTempRR)),
("tpmsBattFL", .number(c.tpmsBattFL)),
("tpmsBattFR", .number(c.tpmsBattFR)),
("tpmsBattRL", .number(c.tpmsBattRL)),
("tpmsBattRR", .number(c.tpmsBattRR)),
// Rive numbers are 32-bit floats, too coarse for epoch milliseconds.
("currentTime", .number(Self.secondsSinceLocalMidnight(currentTime))),
("phoneBattery", .number(Float(phoneBattery))),
Expand Down
Loading