Qualcomm 远程信息处理 SDK - 用户指南(16)
4.8.3 获取/设置自动关机模式
此示例应用程序演示了如何获取/设置热自动关闭模式。
1.获取热工厂实例
auto &thermalFactory = telux::therm::ThermalFactory::getInstance();
2.准备初始化回调
std::promise<telux::common::ServiceStatus> p;
auto initCb = [&p](telux::common::ServiceStatus status) {
std::cout << "Received service status: " << static_cast<int>(status) << std::endl;
p.set_value(status);
};
- 获取热关断管理器实例
thermShutdownMgr_ = thermalFactory.getThermalShutdownManager(initCb);
if(thermShutdownMgr_ == NULL)
{
std::cout << APP_NAME << " *** ERROR - Failed to get manager instance" << std::endl;
return -1;
}
4.等待初始化回调并检查服务状态
telux::common::ServiceStatus serviceStatus = p.get_future().get();
if(serviceStatus == telux::common::ServiceStatus::SERVICE_AVAILABLE) {
std::cout << APP_NAME << " Thermal-Shutdown management services are ready !" << std::endl;
} else {
std::cout << APP_NAME << " *** ERROR - Unable to initialize Thermal-Shutdown management "
"services" << std::endl;
return -1;
}
5.查询当前热敏自动关机模式
// Callback which provides response to query operation
void getStatusCallback(AutoShutdownMode mode)
{
if(mode == AutoShutdownMode::ENABLE) {
std::cout << " Current auto shutdown mode is: Enable" << std::endl;
} else if(mode == AutoShutdownMode::DISABLE) {
std::cout << " Current auto shutdown mode is: Disable" << std::endl;
} else {
std::cout << " *** ERROR - Failed to send get auto-shutdown mode " << std::endl;
}
}
// Send get themal auto shutdown mode command
auto status = thermShutdownMgr_->getAutoShutdownMode(getStatusCallback);
if(status != telux::common::Status::SUCCESS) {
std::cout << "getShutdownMode command failed with error" << static_cast<int>(status) << std::endl;
} else {
std::cout << "Request to query thermal shutdown status sent" << std::endl;
}
- 设置热自动关机模式
// Callback which provides response to set thermal auto shutdown mode command
void commandResponse(ErrorCode error)
{
if(error == ErrorCode::SUCCESS) {
std::cout << " sent successfully" << std::endl;
} else {
std::cout << " failed\n errorCode: " << static_cast<int>(error) << std::endl;
}
}
// Send set themal auto shutdown mode command
auto status = thermShutdownMgr_->setAutoShutdownMode(state, commandResponse);
if(status != telux::common::Status::SUCCESS) {
std::cout << "setShutdownMode command failed with error" << static_cast<int>(status) << std::endl;
} else {
std::cout << "Request to set thermal shutdown status sent" << std::endl;
}
4.9 传感器
4.9.1 配置和获取传感器数据
此示例应用程序演示了如何配置和获取传感器数据。示例应用程序还展示了如何从具有不同配置的同一传感器获取数据
1.获取传感器工厂实例
auto &sensorFactory = telux::sensor::SensorFactory::getInstance();
- 准备传感器子系统初始化完成时调用的回调
std::promise<telux::common::ServiceStatus> p;
auto initCb = [&p](telux::common::ServiceStatus status) {
std::cout << "Received service status: " << static_cast<int>(status) << std::endl;
p.set_value(status);
};
- 获取传感器管理器。如果初始化失败,执行必要的错误处理
std::shared_ptr<telux::sensor::ISensorManager> sensorManager
= sensorFactory.getSensorManager(initCb);
if (sensorManager == nullptr) {
std::cout << "sensor manager is nullptr" << std::endl;
exit(1);
}
std::cout << "obtained sensor manager" << std::endl;
4.等待初始化完成
p.get_future().get();
if (sensorManager->getServiceStatus() != telux::common::ServiceStatus::SERVICE_AVAILABLE) {
std::cout << "Sensor service not available" << std::endl;
exit(1);
}
- 获取有关系统中可用传感器的信息
std::cout << "Sensor service is now available" << std::endl;
std::vector<telux::sensor::SensorInfo> sensorInfo;
telux::common::Status status = sensorManager->getAvailableSensorInfo(sensorInfo);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to get information on available sensors" << static_cast<int>(status)
<< std::endl;
exit(1);
}
std::cout << "Received sensor information" << std::endl;
for (auto info : sensorInfo) {
printSensorInfo(info);
}
- 向 ISensorManager 请求所需的传感器
std::shared_ptr<telux::sensor::ISensorClient> lowRateSensorClient;
std::cout << "Getting sensor: " << name << std::endl;
status = sensorManager->getSensorClient(lowRateSensorClient, name);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to get sensor: " << name << std::endl;
exit(1);
}
- 创建并注册用于配置更新和传感器事件的传感器事件监听器
事件侦听器扩展 ISensorEventListener 以接收有关配置和传感器事件的通知。
class SensorEventListener : public telux::sensor::ISensorEventListener {
public:
SensorEventListener(std::string name, std::shared_ptr<telux::sensor::ISensorClient> sensor)
: name_(name)
, sensorClient_(sensor)
, totalBatches_(0) {
}
// [11] Receive sensor events. This notification is received every time the configured batch
// count is available with the sensor framework
virtual void onEvent(std::shared_ptr<std::vector<telux::sensor::SensorEvent>> events) override {
PRINT_NOTIFICATION << "(" << name_ << "): Received " << events->size()
<< " events from sensor: " << sensorClient_->getSensorInfo().name
<< std::endl;
// I/O intense operations such as below should be avoided since this thread should avoid
// any time consuming operations
for (telux::sensor::SensorEvent s : *(events.get())) {
printSensorEvent(s);
}
++totalBatches_;
// [11.1] If we have received expected number of batches and want to reconfigure the sensor
// we will spawn the request to deactivate, configure and activate on a different thread
// since we are not allowed to invoke the sensor APIs from this thread context
if (totalBatches_ > TOTAL_BATCHES_REQUIRED) {
totalBatches_ = 0;
std::thread t([&] {
sensorClient_->deactivate();
sensorClient_->configure(sensorClient_->getConfiguration());
sensorClient_->activate();
});
// Be sure to detach the thread
t.detach();
}
}
// [9] Receive configuration updates
virtual void onConfigurationUpdate(telux::sensor::SensorConfiguration configuration) override {
PRINT_NOTIFICATION << "(" << name_ << "): Received configuration update from sensor: "
<< sensorClient_->getSensorInfo().name << ": ["
<< configuration.samplingRate << ", " << configuration.batchCount << " ]"
<< std::endl;
}
private:
bool isUncalibratedSensor(telux::sensor::SensorType type) {
return ((type == telux::sensor::SensorType::GYROSCOPE_UNCALIBRATED)
|| (type == telux::sensor::SensorType::ACCELEROMETER_UNCALIBRATED));
}
void printSensorEvent(telux::sensor::SensorEvent &s) {
telux::sensor::SensorInfo info = sensorClient_->getSensorInfo();
if (isUncalibratedSensor(sensorClient_->getSensorInfo().type)) {
PRINT_NOTIFICATION << ": " << sensorClient_->getSensorInfo().name << ": " << s.timestamp
<< ", " << s.uncalibrated.data.x << ", " << s.uncalibrated.data.y
<< ", " << s.uncalibrated.data.z << ", " << s.uncalibrated.bias.x
<< ", " << s.uncalibrated.bias.y << ", " << s.uncalibrated.bias.z
<< std::endl;
} else {
PRINT_NOTIFICATION << ": " << sensorClient_->getSensorInfo().name << ": " << s.timestamp
<< ", " << s.calibrated.x << ", " << s.calibrated.y << ", "
<< s.calibrated.z << std::endl;
}
}
std::string name_;
std::shared_ptr<telux::sensor::ISensorClient> sensorClient_;
uint32_t totalBatches_;
};
创建一个事件侦听器并将其注册到传感器。
std::shared_ptr<SensorEventListener> lowRateSensorClientEventListener
= std::make_shared<SensorEventListener>("Low-rate", lowRateSensorClient);
lowRateSensorClient->registerListener(lowRateSensorClientEventListener);
- 使用所需的配置来配置传感器,设置必要的有效性掩码
telux::sensor::SensorConfiguration lowRateConfig;
lowRateConfig.samplingRate = getMinimumSamplingRate(lowRateSensorClient->getSensorInfo());
lowRateConfig.batchCount = lowRateSensorClient->getSensorInfo().maxBatchCountSupported;
std::cout << "Configuring sensor with samplingRate, batchCount [" << lowRateConfig.samplingRate
<< ", " << lowRateConfig.batchCount << "]" << std::endl;
lowRateConfig.validityMask.set(telux::sensor::SensorConfigParams::SAMPLING_RATE);
lowRateConfig.validityMask.set(telux::sensor::SensorConfigParams::BATCH_COUNT);
status = lowRateSensorClient->configure(lowRateConfig);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to configure sensor: " << name << std::endl;
exit(1);
}
- 接收传感器配置更新
virtual void onConfigurationUpdate(telux::sensor::SensorConfiguration configuration) override {
PRINT_NOTIFICATION << "(" << name_ << "): Received configuration update from sensor: "
<< sensorClient_->getSensorInfo().name << ": ["
<< configuration.samplingRate << ", " << configuration.batchCount << " ]"
<< std::endl;
}
10.激活传感器接收传感器数据
status = lowRateSensorClient->activate();
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to activate sensor: " << name << std::endl;
exit(1);
}
11.使用注册的监听器接收传感器数据
避免在此回调中进行任何耗时的操作。该线程应释放回 SDK 库以避免延迟。
如果需要在此方法中调用任何传感器 API,则应在不同的线程上完成它们。其中一种方法是生成一个调用所需 API 的分离线程。
virtual void onEvent(std::shared_ptr<std::vector<telux::sensor::SensorEvent>> events) override {
PRINT_NOTIFICATION << "(" << name_ << "): Received " << events->size()
<< " events from sensor: " << sensorClient_->getSensorInfo().name
<< std::endl;
// I/O intense operations such as below should be avoided since this thread should avoid
// any time consuming operations
for (telux::sensor::SensorEvent s : *(events.get())) {
printSensorEvent(s);
}
++totalBatches_;
// [11.1] If we have received expected number of batches and want to reconfigure the sensor
// we will spawn the request to deactivate, configure and activate on a different thread
// since we are not allowed to invoke the sensor APIs from this thread context
if (totalBatches_ > TOTAL_BATCHES_REQUIRED) {
totalBatches_ = 0;
std::thread t([&] {
sensorClient_->deactivate();
sensorClient_->configure(sensorClient_->getConfiguration());
sensorClient_->activate();
});
// Be sure to detach the thread
t.detach();
}
}
- 为同一个传感器及其相应的侦听器创建另一个传感器客户端
std::shared_ptr<telux::sensor::ISensorClient> highRateSensorClient;
std::cout << "Getting sensor: " << name << std::endl;
status = sensorManager->getSensorClient(highRateSensorClient, name);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to get sensor: " << name << std::endl;
exit(1);
}
std::shared_ptr<SensorEventListener> highRateSensorEventListener
= std::make_shared<SensorEventListener>("High-rate", highRateSensorClient);
highRateSensorClient->registerListener(highRateSensorEventListener);
- 根据需要使用不同的配置来配置此传感器客户端
telux::sensor::SensorConfiguration highRateConfig;
highRateConfig.samplingRate = getMaximumSamplingRate(highRateSensorClient->getSensorInfo());
highRateConfig.batchCount = highRateSensorClient->getSensorInfo().maxBatchCountSupported;
std::cout << "Configuring sensor with samplingRate, batchCount [" << highRateConfig.samplingRate
<< ", " << highRateConfig.batchCount << "]" << std::endl;
highRateConfig.validityMask.set(telux::sensor::SensorConfigParams::SAMPLING_RATE);
highRateConfig.validityMask.set(telux::sensor::SensorConfigParams::BATCH_COUNT);
status = highRateSensorClient->configure(highRateConfig);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to configure sensor: " << name << std::endl;
exit(1);
}
- 也激活该传感器
status = highRateSensorClient->activate();
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to activate sensor: " << name << std::endl;
exit(1);
}
- 当不再需要数据采集时,停用传感器
status = lowRateSensorClient->deactivate();
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to deactivate sensor: " << name << std::endl;
exit(1);
}
status = highRateSensorClient->deactivate();
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to deactivate sensor: " << name << std::endl;
exit(1);
}
- 如果不再需要,则释放 ISensorClient 实例
lowRateSensorClient = nullptr;
highRateSensorClient = nullptr;
17、释放ISensorManager实例,清理资源
sensorManager = nullptr;
使用Sensor API发起自检并获取自检结果
请按照以下步骤启动自检并获取自检结果
1.获取传感器工
auto &sensorFactory = telux::sensor::SensorFactory::getInstance();
- 准备传感器子系统初始化完成时调用的回调
std::promise<telux::common::ServiceStatus> p;
auto initCb = [&p](telux::common::ServiceStatus status) {
std::cout << "Received service status: " << static_cast<int>(status) << std::endl;
p.set_value(status);
};
- 获取传感器管理器。如果初始化失败,执行必要的错误处理
std::shared_ptr<telux::sensor::ISensorManager> sensorManager
= sensorFactory.getSensorManager(initCb);
if (sensorManager == nullptr) {
std::cout << "sensor manager is nullptr" << std::endl;
exit(1);
}
std::cout << "obtained sensor manager" << std::endl;
4.等待初始化完成
p.get_future().get();
if (sensorManager->getServiceStatus() != telux::common::ServiceStatus::SERVICE_AVAILABLE) {
std::cout << "Sensor service not available" << std::endl;
exit(1);
}
- 获取有关系统中可用传感器的信息
std::cout << "Sensor service is now available" << std::endl;
std::vector<telux::sensor::SensorInfo> sensorInfo;
telux::common::Status status = sensorManager->getAvailableSensorInfo(sensorInfo);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to get information on available sensors" << static_cast<int>(status)
<< std::endl;
exit(1);
}
std::cout << "Received sensor information" << std::endl;
for (auto info : sensorInfo) {
printSensorInfo(info);
}
- 向 ISensorManager 请求所需的传感器
std::shared_ptr<telux::sensor::ISensorClient> sensor;
std::cout << "Getting sensor: " << name << std::endl;
status = sensorManager->getSensorClient(sensor, name);
if (status != telux::common::Status::SUCCESS) {
std::cout << "Failed to get sensor: " << name << std::endl;
exit(1);
}
- 使用所需的自测试类型调用自测试并提供回调
status = sensor->selfTest(selfTestType, [](telux::common::ErrorCode result) {
PRINT_CB << "Received self test response: " << static_cast<int>(result) << std::endl;
});
if (status != telux::common::Status::SUCCESS) {
std::cout << "Self test request failed";
} else {
std::cout << "Self test request successful, waiting for callback" << std::endl;
}
- 如果不再需要,释放 ISensorClient 实例
sensor = nullptr;
9、释放ISensorManager实例,清理资源
sensorManager = nullptr;