首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在IoT设备、python脚本上验证校准过程

在IoT设备、python脚本上验证校准过程
EN

Code Review用户
提问于 2021-05-09 21:55:47
回答 1查看 59关注 0票数 3

我有一个带有加速和陀螺仪传感器的IoT设备。在我的设备可以使用之前,它需要进行校准。

基本上,这意味着我为XYZ轴和陀螺运动做了测量,并将发现保存在JSON文件中。

有了这个脚本,我想确保校准过程已经发生,并且我得到的值在合理的公差内。

轴的值分为正负两部分,围绕着正负的9.81和负的9.81。当我说旋转的时候,我的意思是他们应该有一定的宽容。

陀螺仪的值以同样的公差旋转在0附近。

在校准之前,默认的JSON文件如下所示:

{"acc_x_max": 9.81, "acc_x_min": -9.81, "acc_y_max": 9.81, "acc_y_min": -9.81, "acc_z_max": 9.81, "acc_z_min": -9.81, "gyro_x_offset": 0, "gyro_y_offset": 0, "gyro_z_offset": 0}

我希望您对此脚本的最重要的奏鸣曲方式和最佳实践有很好的反馈:

代码语言:javascript
复制
import logging
import sys

# Defining logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(levelname)s - %(message)s')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)

# Defining constants
G = 9.81
TOLERANCE = 2.0
AXES_ARGS = ['acc_x_max', 'acc_y_max', 'acc_z_max', 'acc_x_min', 'acc_y_min', 'acc_z_min']
GYRO_OFFSETS = ['gyro_x_offset', 'gyro_y_offset', 'gyro_z_offset']
PATH_TO_CALIBRATION_FILE = '/home/pi/Desktop/device/IMU_calibration.json'
FIXING_CALIBRATION_MSG = 'please calibrated by running "sudo sh IoT/calibration.sh" ' \
                         'from /home/pi/Desktop/device directory '
CALIBRATION_ARGS = AXES_ARGS + GYRO_OFFSETS


def main():
    calib_dict = get_calibration_dictionary(PATH_TO_CALIBRATION_FILE)
    checking_if_calibration_file_has_been_changed(calib_dict)
    verify_calibration_in_tolerance_range()
    logger.info('Device is calibrated !!! :)')


def is_calibration_in_tolerance(data: str, tolerance: float, g_force: float):
    """
    This function takes a value and assesses if it stands in the calibration standards.
    @param g_force: float
    @param data: str - acc axes key or gyro offset key
    @param tolerance: the range which defines valid results in calibration accuracy.
    @return: None
    """
    calib_dict = get_calibration_dictionary(PATH_TO_CALIBRATION_FILE)
    if not abs(calib_dict[data] - g_force) <= tolerance:
        logger.error(data + f' seems out of calibration\n {FIXING_CALIBRATION_MSG}')
        exit(1)


def get_calibration_dictionary(path_to_calibration_file) -> dict:
    """
    This function verifying if the calibration file exists in the path and if it does;
    it returns the calibration data as a python dictionary.
    @param path_to_calibration_file: str - path to the calibration file.
    @return: python dictionary
    """
    try:
        with open(path_to_calibration_file) as f:
            return json.load(f)
    except FileNotFoundError:
        raise FileNotFoundError(f'cant find calibration file at: {path_to_calibration_file}')


def checking_if_calibration_file_has_been_changed(calib_dict: dict) -> None:
    calibration_file_did_not_change_error_msg = f'This Device hasn\'t been calibrated\n {FIXING_CALIBRATION_MSG}'

    # Checking if axes have been calibrated or they still hold their default values
    for axis in AXES_ARGS:
        if 'max' in axis and calib_dict[axis] == G:
            logger.error(calibration_file_did_not_change_error_msg)
            exit(1)
        if 'min' in axis and calib_dict[axis] == -G:
            logger.error(calibration_file_did_not_change_error_msg)
            exit(1)

    # Checking if gyro offsets have been calibrated or they still hold their default values
    for gyro_offset in GYRO_OFFSETS:
        if calib_dict[gyro_offset] == 0:
            logger.error(gyro_offset + calibration_file_did_not_change_error_msg)
            exit(1)


def verify_calibration_in_tolerance_range() -> None:
    """
    This function checks if the calibration values are in the tolerance range.
    It differentiates the input data according to its key and supplies "is_calibration_in_tolerance"
    function with suitable arguments.
    If the tested value does no meet the criteria it will exit with the return value of 1.
    If all the values meet the standard it returns None.
    @return: None
    """

    # verifying axes calibration in tolerance range
    for calib_key in CALIBRATION_ARGS:
        if 'max' in calib_key:
            is_calibration_in_tolerance(calib_key, TOLERANCE, G)
        elif 'min' in calib_key:
            is_calibration_in_tolerance(calib_key, TOLERANCE, -G)
        elif 'gyro' in calib_key:
            is_calibration_in_tolerance(calib_key, TOLERANCE, 0.0)


if __name__ == '__main__':
    main()
EN

回答 1

Code Review用户

回答已采纳

发布于 2021-05-10 20:34:04

你用的是日志-太棒了!您应该封装日志设置,这样就不会污染全局命名空间,比如

代码语言:javascript
复制
def make_logger():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(levelname)s - %(message)s')
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger

logger = make_logger()

海平面的重力加速度标准值不是9.81,而是9.80665。

AXES_ARGSGYRO_OFFSETS应该是元组,而不是列表,因为它们是不可变的。

如果用户以交互模式提供/home值,则可以在D5中使用该值。但是,在/home中默认某些内容是个坏主意。因为这看起来像是IOT设备上的永久服务,所以请让一个实际的(非pi)服务用户注意标准Unix文件布局的建议。根据几点不同,您的校准文件(如果是集中式的)在权限中更好-- /usr/share/usr/local/share的受限子目录,如果它被认为是“静态配置”,则可能是/etc/;或者如果它被认为是“运行时数据”,则可能是/var/。如果它不是集中式的,并且需要一个交互式用户(这似乎不太可能),那么您应该在命令行上接受这个路径。

语法:please calibrated -> please calibrate

要求用户在sudo下运行D15是很糟糕的。请不要对IOT是一个巨大的不安全的荒地的刻板印象作出贡献-你的用户模型需要清理。校准代码中的任何内容都不需要根访问。

这基本上是不允许的:

代码语言:javascript
复制
    except FileNotFoundError:
        raise FileNotFoundError(f'cant find calibration file at: {path_to_calibration_file}')

所以,删除它,让原来的异常通过。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/260542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档