MPU6050 参数读取 Jetson
编译动态链接库
I2CDevLib仓库
选用Linux上驱动I2C和MPU6050的代码,克隆LinuxI2CDev文件夹到本地,然后进入到文件夹中,创建一个main.cpp用来创建与Python的函数接口,可以自定义。这里的代码没有考虑零偏,只是从DMP取出四元数换算得到结果的,实际用的时候有不小的零偏,可以添加上初始化时的零偏纠正过程。
#include <stdio.h> #include "MPU6050/MPU6050_6Axis_MotionApps20.h" extern "C" { MPU6050 mpu; bool dmp_initialized = false; void initialize_dmp() { mpu.initialize(); if (!mpu.testConnection()) { printf("MPU6050 connection failed\n"); return; } if (mpu.dmpInitialize() != 0) { printf("DMP initialization failed\n"); return; } mpu.setDMPEnabled(true); dmp_initialized = true; } void get_yaw_pitch_roll(float *yaw, float *pitch, float *roll) { if (!dmp_initialized) { printf("DMP not initialized\n"); return; } uint16_t packetSize = mpu.dmpGetFIFOPacketSize(); uint8_t fifoBuffer[64]; if (mpu.dmpPacketAvailable()) { mpu.dmpGetCurrentFIFOPacket(fifoBuffer); Quaternion q; mpu.dmpGetQuaternion(&q, fifoBuffer); VectorFloat gravity; mpu.dmpGetGravity(&gravity, &q); float ypr[3]; mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); *yaw = ypr[0]; *pitch = ypr[1]; *roll = ypr[2]; } } }
|
配置CmakeLists.txt,当然,在配置成动态链接库之前,可以编译成可执行程序验证正确性。
cmake_minimum_required(VERSION 3.10)
project(MPU6050_Project)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_library(I2Cdev I2Cdev/I2Cdev.cpp) target_include_directories(I2Cdev PUBLIC I2Cdev)
add_library(MPU6050 MPU6050/MPU6050.cpp MPU6050/MPU6050_6Axis_MotionApps20.cpp) target_include_directories(MPU6050 PUBLIC MPU6050)
target_link_libraries(MPU6050 I2Cdev)
add_library(mpu6050_lib SHARED main.cpp) target_include_directories(mpu6050_lib PUBLIC .)
target_link_libraries(mpu6050_lib MPU6050)
|
创建build文件夹,进入build文件夹,执行cmake ..,然后make,即可看到libmpu6050_lib.so,记住路径,或者移动到python代码同目录下
调用和获取数据
使用如下代码,可以加载并自动获取yaw, pitch,
roll角度。这里使用单独的线程,因为不连续读取时会出现错误数据,原因未知。
lib = ctypes.CDLL('./cpp/libmpu6050_lib.so')
lib.initialize_dmp.argtypes = [] lib.initialize_dmp.restype = None
lib.get_yaw_pitch_roll.argtypes = [ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_float)] lib.get_yaw_pitch_roll.restype = None
lib.initialize_dmp()
yaw = ctypes.c_float() pitch = ctypes.c_float() roll = ctypes.c_float()
lock = threading.Lock() stop_event = threading.Event()
def yaw_read_thread(): global stop_event try: while True: with lock: lib.get_yaw_pitch_roll(ctypes.byref(yaw), ctypes.byref(pitch), ctypes.byref(roll)) finally: stop_event.set()
threading.Thread(target=yaw_read_thread, daemon=True).start()
|