DRIVE OS Version: DRIVE OS version: 6.0.10
Issue Description:
Goal:
- Feeding egomotion via a custom CAN parser (Bypasse the VehicleIO API)
- No IMU (DW_EGOMOTION_ODOMETRY)
Problem
- Reasonable/Plausible values for
front steering angle,wheel speedsandspeed ESCbut all estimations of egomotion stays zero and the quality for all values contains the statusINVALID(with bounds [0,0]) (see logs below) even ifdwEgomotion_addVehicleIOStatereturnsDW_SUCCESS
Details
- I logged the values via
m_vioNonSafety.speedESCTimestampetc:- speedESC: ~ 1.74 m/s
- wheel speeds: all ~ 4.8 rad/s
- front steering angle: ~ 0 rad (makes sense, driving straight ahead)
statusofdwEgomotion_addVehicleIOStateist alwaysDW_SUCCESS- valid flags of estimation always 327
- timestamps (dwEgomotion_getEstimationTimestamp()) plausible and monotonically increasing
Code Snippet
dwVehicleIOSafetyState m_vioSafety{};
dwVehicleIONonSafetyState m_vioNonSafety{};
dwVehicleIOActuationFeedback m_vioAct{};
...
CHECK_DW_ERROR_MSG(dwCANInterpreter_buildFromDBC(&m_aCanInterpreter, m_dbcFile_acan.c_str(), m_context),
"Error:Cannot create DBC-based A-CAN message interpreter");
...
CHECK_DW_ERROR_MSG(dwCANInterpreter_consume(&msg, m_aCanInterpreter), "Consume message failed");
dwStatus status_num = dwCANInterpreter_getNumberSignals(&num, m_aCanInterpreter);
for (uint32_t i = 0; i < num; ++i) // alle Signale durchgehen
{
dwStatus status_name = dwCANInterpreter_getSignalName(&name, i, m_aCanInterpreter);
if (status_name== DW_SUCCESS && status_num==DW_SUCCESS && num>0)
{
dwStatus status = dwCANInterpreter_getf32(&value, ×tamp, i, m_aCanInterpreter);
timestamp = msg.timestamp_us;
if (status != DW_SUCCESS)
{
std::cout << "Get value and timestamp of signal" << i << "failed" << std::endl;
}
if (status == DW_SUCCESS && timestamp > 0)
{
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Read from CAN data and fill vehicle state structs
//////////////////////////////////////////////////////////////////////////////////////////////////////
if (strcmp(name, "ESP_21.ESP_v_Signal") == 0) // "ESP_21.ESP_v_Signal"
{
m_vioNonSafety.speedESC = value * (1000.0f/3600.0f);
m_vioNonSafety.speedESCTimestamp = timestamp;
setSignalValid(&m_vioNonSafety.validityInfo.speedESC);
setSignalValid(&m_vioNonSafety.validityInfo.speedESCTimestamp);
m_haveSpeedESC = true;
}
... // (same for m_vioNonSafety.wheelSpeed [0,1,2,3], m_vioNonSafety.wheelTicksTimestam[0,1,2,3], m_vioNonSafety.frontSteeringAngle and m_vioNonSafety.validityInfo.frontSteeringTimestamp)
}
}
}
if (m_haveSteering && m_haveSpeedESC && m_haveWheelSpeeds)
{
if (m_lastEgoMotionAddedTime < msg.timestamp_us)
{
dwStatus status = dwEgomotion_addVehicleIOState(&m_vioSafety, &m_vioNonSafety, &m_vioAct, m_egomotion); // In case relevant new information is contained in this state then it gets consumed, otherwise state is ignored
m_lastEgoMotionAddedTime = sensorEvent->timestamp_us; // ggf msg.timestamp_us
}
}
Detailed logs
Logs
---- Values ----
Added vehicleio state to egomotion module: steering angle (rad): -0.0104719763621688
front steering angle (rad): -0.000707565923221409
wheel speeds (rad/s): [4.93203067779541, 4.90873908996582, 4.94367647171021, 4.92620754241943]
speed ESC (m/s): 1.76111125946045
---- Timestamps ----
Added vehicleio state times to egomotion module: steering angle timestamp: 1767810981213747
wheel speed timestamps (rad/s): [1767810981216987, 1767810981216987, 1767810981216987, 1767810981216987]
speed ESC timestamp: 1767810981207722
---- Egomotion Estimation Availability ----
Egomotion estimation available: Yes
---- Motion Model Type ----
DW_EGOMOTION_ODOMETRY
---- Validities ----
Signal Validities: DW_SUCCESS
DW_SUCCESS
DW_SUCCESS, DW_SUCCESS, DW_SUCCESS, DW_SUCCESS, DW_SUCCESS
---- Latest Egomotion Estimate ----
Egomotion estimate timestamp: 1767810981213747
timestamp_us: 1767810981213747
linearVelocity (m/s): [0, 0, 0]
linearAcceleration (m/s^2): [0, 0, 0]
angularVelocity (rad/s): [0, 0, 0]
angularAcceleration (rad/s^2): [0, 0, 0]
rotation (quat w,x,y,z): [1, 0, 0, 0]
validFlags: 327
Quality: (printed in detail)
linVel.x status=INVALID bounds=[0, 0]
linVel.y status=INVALID bounds=[0, 0]
linVel.z status=INVALID bounds=[0, 0]
angVel.x status=INVALID bounds=[0, 0]
angVel.y status=INVALID bounds=[0, 0]
angVel.z status=INVALID bounds=[0, 0]
rot.roll status=INVALID bounds=[0, 0]
rot.pitch status=INVALID bounds=[0, 0]
Code for logs
std::cout << "---- Values ----" << std::endl;
std::cout << "Added vehicleio state to egomotion module: steering angle (rad): " << m_vioSafety.steeringWheelAngle << std::endl;
std::cout << "front steering angle (rad): " << m_vioNonSafety.frontSteeringAngle << std::endl;
std::cout << "wheel speeds (rad/s): [" << m_vioNonSafety.wheelSpeed[0] << ", " << m_vioNonSafety.wheelSpeed[1] << ", "
<< m_vioNonSafety.wheelSpeed[2] << ", " << m_vioNonSafety.wheelSpeed[3] << "]" << std::endl;
std::cout << "speed ESC (m/s): " << m_vioNonSafety.speedESC << std::endl;
std::cout << "-----------------------------------" << std::endl;
std::cout << "---- Timestamps ----" << std::endl;
std::cout << "Added vehicleio state times to egomotion module: steering angle timestamp: " << m_vioNonSafety.frontSteeringTimestamp << std::endl;
std::cout << "wheel speed timestamps (rad/s): [" << m_vioNonSafety.wheelTicksTimestamp[0] << ", " << m_vioNonSafety.wheelTicksTimestamp[1] << ", "
<< m_vioNonSafety.wheelTicksTimestamp[2] << ", " << m_vioNonSafety.wheelTicksTimestamp[3] << "]" << std::endl;
std::cout << "speed ESC timestamp: " << m_vioNonSafety.speedESCTimestamp << std::endl;
std::cout << "-----------------------------------" << std::endl;
// check if egomotion estimation is available loggen
bool estimationAvailable = false;
dwStatus estimation_status = dwEgomotion_hasEstimation(&estimationAvailable, m_egomotion);
std::cout << "---- Egomotion Estimation Availability ----" << std::endl;
if (estimation_status != DW_SUCCESS)
{
std::cout << "Check if egomotion estimation is available failed" << std::endl;
}
else
{
std::cout << "Egomotion estimation available: " << (estimationAvailable ? "Yes" : "No") << std::endl;
}
std::cout << "-----------------------------------" << std::endl;
}
// check which motion model type is currently used in egomotion loggen
dwMotionModel motionModelType;
dwStatus motionmodel_status = dwEgomotion_getMotionModel(&motionModelType, m_egomotion);
std::cout << "---- Motion Model Type ----" << std::endl;
if (motionmodel_status != DW_SUCCESS)
{
std::cout << "Check motion model type failed" << std::endl;
}
else
{
switch(motionModelType)
{
case DW_EGOMOTION_ODOMETRY:
std::cout << "DW_EGOMOTION_ODOMETRY" << std::endl;
break;
case DW_EGOMOTION_IMU_ODOMETRY :
std::cout << "DW_EGOMOTION_IMU_ODOMETRY" << std::endl;
break;
case DW_EGOMOTION_VEHICLE_MOTION_OBSERVER :
std::cout << "DW_EGOMOTION_VEHICLE_MOTION_OBSERVER" << std::endl;
break;
default: break;
}
}
std::cout << "-----------------------------------" << std::endl;
}
std::cout << "---- Validities ----" << std::endl;
std::cout << "Signal Validities: " << dwGetStatusName(dwSignal_checkSignalValidity(m_vioSafety.validityInfo.steeringWheelAngle)) << std::endl;
std::cout << dwGetStatusName(dwSignal_checkSignalValidity(m_vioNonSafety.validityInfo.frontSteeringAngle)) << std::endl;
std::cout <<dwGetStatusName(dwSignal_checkSignalValidity(m_vioNonSafety.validityInfo.wheelSpeed[0])) << ", " << dwGetStatusName(dwSignal_checkSignalValidity(m_vioNonSafety.validityInfo.wheelSpeed[1])) << ", "
<< dwGetStatusName(dwSignal_checkSignalValidity(m_vioNonSafety.validityInfo.wheelSpeed[2])) << ", " << dwGetStatusName(dwSignal_checkSignalValidity(m_vioNonSafety.validityInfo.wheelSpeed[3])) << ", "
<< dwGetStatusName(dwSignal_checkSignalValidity(m_vioNonSafety.validityInfo.speedESC))
<< std::endl;
std::cout << "-----------------------------------" << std::endl;
dwEgomotionResult m_latestEgoEstimate {};
dwTime_t estimate_timestamp = 0;
dwStatus status = dwEgomotion_getEstimation(&m_latestEgoEstimate, m_egomotion);
dwStatus timestamp_status = dwEgomotion_getEstimationTimestamp(&estimate_timestamp, m_egomotion);
// Print egomotion state estimate
if (status != DW_SUCCESS && timestamp_status != DW_SUCCESS)
{
std::cout << "Get latest egomotion estimate failed, status: " << dwGetStatusName(status) << std::endl;
}
else
{
std::cout << "---- Latest Egomotion Estimate ----" << std::endl;
std::cout << "Egomotion estimate timestamp: " << estimate_timestamp << std::endl;
std::cout << " timestamp_us: " << m_latestEgoEstimate.timestamp << std::endl;
std::cout << " linearVelocity (m/s): [" << m_latestEgoEstimate.linearVelocity[0] << ", "<< m_latestEgoEstimate.linearVelocity[1] << ", " << m_latestEgoEstimate.linearVelocity[2] << "]" << std::endl;
std::cout << " linearAcceleration (m/s^2): [" << m_latestEgoEstimate.linearAcceleration[0] << ", "<< m_latestEgoEstimate.linearAcceleration[1] << ", " << m_latestEgoEstimate.linearAcceleration[2] << "]" << std::endl;
std::cout << " angularVelocity (rad/s): [" << m_latestEgoEstimate.angularVelocity[0] << ", "<< m_latestEgoEstimate.angularVelocity[1] << ", " << m_latestEgoEstimate.angularVelocity[2] << "]" << std::endl;
std::cout << " angularAcceleration (rad/s^2): [" << m_latestEgoEstimate.angularAcceleration[0] << ", "<< m_latestEgoEstimate.angularAcceleration[1] << ", " << m_latestEgoEstimate.angularAcceleration[2] << "]" << std::endl;
std::cout << " rotation (quat w,x,y,z): [" << m_latestEgoEstimate.rotation.w << ", "<< m_latestEgoEstimate.rotation.x << ", " << m_latestEgoEstimate.rotation.y << ", "<< m_latestEgoEstimate.rotation.z << "]" << std::endl;
std::cout << " validFlags: " << m_latestEgoEstimate.validFlags << std::endl;
std::cout << "-----------------------------------" << std::endl;
std::cout << " Quality: (printed in detail)" << std::endl;
dumpEgomotionQuality(m_latestEgoEstimate);
std::cout << "-----------------------------------" << std::endl;
}