예제 #1
0
    def __init__(self, init_state=Quaternion(1, 0, 0, 0), target_freq=30.0):
        """Initialize IMU bus connection, filter and threading.

        Initialize a bus connection to the ICM20948 IMU, a MadgwickAHRS
        filter for filtering noisy sensor data, and a deamon thread
        for background updating.

        Args:
            init_state (madgwick_py.quaternion, optional): Initial state of the filter. Defaults to Quaternion(1, 0, 0, 0).
            target_freq (float, optional): Target update frequency. Defaults to 30.0.
        """

        self.lock = threading.Lock()

        self.target_freq = target_freq

        self.imu = ICM20948(i2c_bus=SMBus(0))

        self.filter = MadgwickAHRS(
            sampleperiod=1.0 / target_freq,
            quaternion=init_state,
            beta=0.05,
        )

        thread = threading.Thread(target=self.__update, args=())
        thread.daemon = True
        thread.start()
예제 #2
0
def test_accel_gyro(smbus):
    from icm20948 import ICM20948
    icm20948 = ICM20948()
    ax, ay, az, gx, gy, gz = icm20948.read_accelerometer_gyro_data()
    assert (round(ax, 2), round(ay, 2), round(az, 2), int(gx), int(gy),
            int(gz)) == (0.05, 0.11, 0.16, 3, 4, 5)
    del icm20948
예제 #3
0
 def __init__(self, config, level):
     super().__init__()
     self._log = Logger('imu', level)
     if config is None:
         raise ValueError('no configuration provided.')
     _config = config['ros'].get('imu')
     self._icm20948 = ICM20948(i2c_addr=0x69)
     self._log.info('ready.')
예제 #4
0
def test_setup_present():
    smbus = mock.Mock()
    smbus.SMBus = MockSMBus
    sys.modules['smbus'] = smbus

    from icm20948 import ICM20948
    icm20948 = ICM20948()
    del icm20948
예제 #5
0
def test_setup():
    sys.modules['smbus'] = mock.Mock()

    from icm20948 import ICM20948

    with pytest.raises(RuntimeError):
        icm20948 = ICM20948()
        del icm20948
예제 #6
0
def get_icm20948_object():
    global __icm20948

    from icm20948 import ICM20948
    from bus import get_i2c_object

    if __icm20948 is None:
        __icm20948 = ICM20948(get_i2c_object())
    return __icm20948
예제 #7
0
def test_accel_gyro():
    smbus = mock.Mock()
    smbus.SMBus = MockSMBus
    sys.modules['smbus'] = smbus

    from icm20948 import ICM20948
    icm20948 = ICM20948()
    ax, ay, az, gx, gy, gz = icm20948.read_accelerometer_gyro_data()
    assert (round(ax, 2), round(ay, 2), round(az, 2), int(gx), int(gy), int(gz)) == (0.05, 0.11, 0.16, 3, 4, 5)
    del icm20948
예제 #8
0
 def __init__(self, config, level):
     super().__init__()
     self._log = Logger('imu', level)
     if config is None:
         raise ValueError('no configuration provided.')
     _config = config['ros'].get('imu')
     self._icm20948 = ICM20948(i2c_addr=0x69)
     self._amin = list(self._icm20948.read_magnetometer_data())
     self._amax = list(self._icm20948.read_magnetometer_data())
     self._log.info('amin: {}; amax: {}'.format(type(self._amin), type(self._amax)))
     self._log.info('ready.')
예제 #9
0
def sensor_data():
    from icm20948 import ICM20948
    imu = ICM20948()
    x, y, z = imu.read_magnetometer_data()
    ax, ay, az, gx, gy, gz = imu.read_accelerometer_gyro_data()
    heading_azimuth = 90 - np.arctan2(x, y) * 180 / np.pi
    data = {'heading_azimuth': heading_azimuth}
    response = app.response_class(response=json.dumps(data),
                                  status=200,
                                  mimetype='application/json')
    return response
예제 #10
0
    def __init__(self, config, level):
        self._log = Logger("imu", level)
        if config is None:
            raise ValueError("no configuration provided.")
        # ICM20948 configuration .....................................
        _icm20948_config = config['ros'].get('icm20948')
        self._icm20948_heading_trim = _icm20948_config.get('heading_trim')
        self._log.info('trim: heading: {:<5.2f}° (ICM20948)'.format(
            self._icm20948_heading_trim))
        self._icm20948 = ICM20948(i2c_addr=0x69)
        self._amin = list(self._icm20948.read_magnetometer_data())
        self._amax = list(self._icm20948.read_magnetometer_data())
        # BNO055 configuration .......................................
        self._bno055 = BNO055(config, Level.INFO)

        self._log.info('ready.')
예제 #11
0
def reset():
    global imu
    logger.warning("Resetting motion sensor ICM20948")
    logger.info("Waiting 5 seconds..")
    time.sleep(5)
    logger.info("Resetting ICM20948 sensor")
    try:
        imu = ICM20948()
        logger.info("Reset complete")
    except Exception as exception:
        logger.error('Unable to restart ICM20948 due to {}'.format(exception),
                     exc_info=True)
        raise Exception(exception)

    test_mx, test_my, test_mz = imu.read_magnetometer_data()
    test_ax, test_ay, test_az, test_gx, test_gy, test_gz = imu.read_accelerometer_gyro_data(
    )
    logger.info(
        f'initial data from ICM20948 ax:${test_ax}, ay:${test_ay}, az:${test_az}, gx:${test_gx}, sgy:${test_gy}, sgz:${test_gz}, mx:${test_mx}, my:${test_my}, mz:${test_mz})'
    )
예제 #12
0
def test_setup(smbus_fail):
    from icm20948 import ICM20948

    with pytest.raises(RuntimeError):
        icm20948 = ICM20948()
        del icm20948
예제 #13
0
def test_setup_present(smbus):
    from icm20948 import ICM20948
    icm20948 = ICM20948()
    del icm20948
 def __init__(self, gyro_offsets=None, mag_offsets=None):
     self._imu = ICM20948()
     self.gyro_offsets = gyro_offsets or vector(0, 0, 0)
     self.mag_offsets = mag_offsets or vector(0, 0, 0)
예제 #15
0
import smbus
import time
from icm20948 import ICM20948
from dryer import Dryer

if __name__ == '__main__':
  icm20948 = ICM20948()
 

  dryer = Dryer()
  while True:
    ax, ay, az, gx, gy, gz = icm20948.read_accelerometer_gyro_data()
    mx, my, mz = icm20948.read_magnetometer_data()
    t = int(time.time())
    print(f'{t} {ax} {ay} {az} {gx} {gy} {gz} {mx} {my} {mz}')
    dryer.add_reading(ax, ay, az, gx, gy, gz, mx, my, mz)
    time.sleep(1)
예제 #16
0
 def __init__(self):
     self._imu = ICM20948()
예제 #17
0
def test_magnetometer(smbus):
    from icm20948 import ICM20948
    icm20948 = ICM20948()
    x, y, z = icm20948.read_magnetometer_data()
    assert (round(x, 2), round(y, 2), round(z, 2)) == (16.65, 33.3, 49.95)
    del icm20948
예제 #18
0
def test_temperature(smbus):
    from icm20948 import ICM20948
    icm20948 = ICM20948()
    temp_degrees = icm20948.read_temperature()
    assert (round(temp_degrees, 2) == 24)
예제 #19
0
파일: drone.py 프로젝트: FerumFist/Icarus
import smbus
from icm20948 import ICM20948
import numpy as np
from servoctl import PCA9685
from baro import *
import serial

SERIAL_PORT = "/dev/ttyACM0"
running = True

CONTROLLER_IP = "10.102.162.242"
# CONTROLLER_IP = "10.253.0.3"
CONTROLLER_TELE_PORT = 8888
CONTROLLER_VIDEO_PORT = 8890

imu = ICM20948()

THROTTLE_SERVO = 0
ELEVATOR_SERVO = 1
YAW_SERVO = 2
AILERON_SERVO_1 = 3
AILERON_SERVO_2 = 4

AIL_1 = 2150
AIL_2 = 2150

# DATA INIT
start_time = time.time()  # start time
ds = 0  # data counter
ds_mean = [0, 0, 0, 0, 0]
ds_iter = 0
def log():
    # declaring a bunch of global variables that will be used accross threads
    global p
    global t
    global t_0
    global t_run
    t_run = 0

    global index
    # initialise variables

    index = 0

    # initialise IMU object
    imu = ICM20948()

    # audio recording parameters
    INDEX = 2
    CHUNK = 1024
    FORMAT = pyaudio.paInt32
    CHANNELS = 1
    RATE = 44100
    RECORD_SECONDS = 40
    WAVE_OUTPUT_FILENAME = "/home/pi/Desktop/Crimson/output.wav"

    # Create the I2C interface for the screen
    i2c = busio.I2C(SCL, SDA)

    # Create the SSD1306 OLED class.
    disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)

    # Clear display.
    disp.fill(0)
    disp.show()

    # Create blank image for drawing.
    # Make sure to create image with mode '1' for 1-bit color.
    width = disp.width
    height = disp.height
    image = Image.new("1", (width, height))

    # Get drawing object to draw on image.
    draw = ImageDraw.Draw(image)

    # Draw a black filled box to clear the image.
    draw.rectangle((0, 0, width, height), outline=0, fill=0)

    # Draw some shapes.
    # First define some constants to allow easy resizing of shapes.
    padding = -2
    top = padding
    bottom = height - padding
    # Move left to right keeping track of the current x position for drawing shapes.
    x = 0

    # Load nice silkscreen font
    font = ImageFont.truetype("/home/pi/Desktop/Crimson/slkscr.ttf", 18)

    # Draw a black filled box to clear the image.
    draw.rectangle((0, 0, width, height), outline=0, fill=0)

    # Display RECORDING label on screen
    draw.text((x, top + 0), "RECORDING... ", font=font, fill=255)
    disp.image(image)
    disp.show()

    # class to handle logging accelerometer data
    class accel_recording:
        # When you initialise an instance of class, the ._running flag is set to True
        def __init__(self):
            self._running = True

        # when you terminate the instance of the class, the _running flag is set to False
        def terminate(self):
            self._running = False
            print("logging session finished")

        # What happens after the class is initialised
        def run(self):
            # first create a csv file top to save all the logged data
            with open("/home/pi/Desktop/Crimson/sensor_log.csv",
                      "a",
                      newline="") as log:
                # create an instance of csv writer
                csv_write = csv.writer(log)

                # write header file
                csv_write.writerow(
                    ["Index", "Timestamp", "Ax", "Ay", "Az", "Gx", "Gy", "Gz"])

                # start time
                global t_0
                t_0 = time.time()

                while self._running:
                    global index
                    global t
                    global t_run
                    # read IMU data
                    ax, ay, az, gx, gy, gz = imu.read_accelerometer_gyro_data()

                    # increment index counter
                    index = index + 1

                    # save IMU data in a row
                    # right now we don't use gyroscope data. however it can be used later to supplement raising/lowering
                    # of the arm detection with an exoskeleton mounted sensor
                    log_row = [
                        index,
                        datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                        ax,
                        ay,
                        az,
                        gx,
                        gy,
                        gz,
                    ]

                    # write row to csv file
                    csv_write.writerow(log_row)
                    t = time.time()
                    # the sampling timing isn't precise at all but that doens't matter for our application
                    # half a second precision is enough to get the results we want. therefore a rough estimate
                    # of the loop time is used here to find time elapsed.
                    t_run = t - t_0
                    time.sleep(0.01)

    class mic_recording:
        def __init__(self):
            self._running = True

        def terminate(self):
            self._running = False

        def run(self):
            p = pyaudio.PyAudio()

            stream = p.open(
                format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                input_device_index=INDEX,
                frames_per_buffer=CHUNK,
            )

            print("* recording")

            frames = []

            for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
                data = stream.read(CHUNK, exception_on_overflow=False)
                frames.append(data)

            print("* done recording")

            stream.stop_stream()
            stream.close()
            p.terminate()

            wf = wave.open(WAVE_OUTPUT_FILENAME, "wb")
            wf.setnchannels(CHANNELS)
            wf.setsampwidth(p.get_sample_size(FORMAT))
            wf.setframerate(RATE)
            wf.writeframes(b"".join(frames))
            wf.close()

    # create Class
    mic_1 = mic_recording()
    # Create_Thread
    mic_Thread = Thread(target=mic_1.run)
    # start Thread
    mic_Thread.start()

    # the recording and accelerometer logging don't start at the same time because of differences in initialisation processes
    # this is not a clean way of doing things but gets the job done realigning them
    time.sleep(0.3)

    # Create Class
    imu_1 = accel_recording()
    # Create Thread
    imu_Thread = Thread(target=imu_1.run)
    # Start Thread
    imu_Thread.start()

    Exit = False  # Exit flag
    while t_run <= 40.0:

        if t_run > 45.0:
            Exit = True  # Exit Program

    imu_1.terminate()
    mic_1.terminate()

    # here you can split the files in ax, ay, az
    # import csv file
    df = pd.read_csv("/home/pi/Desktop/Crimson/sensor_log.csv", header=0)

    df_ax = df[["Ax"]].copy()
    # print(df_ax.head())
    df_ax.Ax = pd.to_numeric(df_ax.Ax, errors="coerce")

    df_ax.to_csv(r"/home/pi/Desktop/Crimson/ax.csv", index=False)

    # ay dataset
    df_ay = df[["Ay"]].copy()
    # print(df_ay.head())
    df_ay.Ay = pd.to_numeric(df_ay.Ay, errors="coerce")
    df_ay.to_csv(r"/home/pi/Desktop/Crimson/ay.csv", index=False)

    df_az = df[["Az"]].copy()
    # print(df_az.head())
    df_az.Az = pd.to_numeric(df_az.Az, errors="coerce")
    df_az.to_csv(r"/home/pi/Desktop/Crimson/az.csv", index=False)

    # Draw a black filled box to clear the image.
    draw.rectangle((0, 0, width, height), outline=0, fill=0)

    # Display RECORDING label on screen
    draw.text((x, top + 0), "Done", font=font, fill=255)
    draw.text((x, top + 16), "Recording", font=font, fill=255)
    disp.image(image)
    disp.show()
    time.sleep(2)

    if __name__ == "__main__":
        log()