• DepthAI-v2
  • Can't get Standalone mode to work with just IMU

Hi,

I working on a standalone application for the Oadk-D-POE and I thought to start getting the IMU data out via MQTT. I cobbled together the code below with a switch to run the script connected or standalone. The code works perfectly in connected mode, but in standalone mode nothing happens. What am I doing wrong?

Dirkjan

P.S. to run the code you need paho-mqtt.py from here

import depthai as dai
import marshal

client = True

# Start defining a pipeline
pipeline = dai.Pipeline()

# Define sources and outputs
imu = pipeline.create(dai.node.IMU)

# enable ROTATION_VECTOR at 400 hz rate
imu.enableIMUSensor(dai.IMUSensor.ROTATION_VECTOR, 100)
imu.setBatchReportThreshold(20)
imu.setMaxBatchReports(20)

# Script node
script = pipeline.create(dai.node.Script)
script.setProcessor(dai.ProcessorType.LEON_CSS)

imu.out.link(script.inputs['quaternions'])

script_text = f"""
    import time
    import socket
    import struct
    import json

    def get_ip_address(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        from fcntl import ioctl
        return socket.inet_ntoa(ioctl(
            s.fileno(),
            -1071617759,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15].encode())
        )[20:24])
    
    mqttc = Client()
    mqttc.connect("192.168.100.33", 1883, 60)

    mqttc.loop_start()
    ip = get_ip_address('re0')  # '192.168.0.110'
    msg = {{'device': 'Luxonis OAK-D-POE', 'settings': {{'mode': '{"client" if client else "standalone"}' }}, 'ip': {{'addr': ip }} }}
    info = mqttc.publish("Antea_test_topic/alive", json.dumps(msg))
    
    while True:
        rv = node.io['quaternions'].get().packets[0].rotationVector
        rv_d = {{'i': rv.i, 'j': rv.j, 'k': rv.k, 'real': rv.real }}
        msg = json.dumps(dict(rv_d))
        info = mqttc.publish("Antea_test_topic/quat_antea", msg)

"""
# print(script_text)
with open("paho-mqtt.py", "r") as f:
    paho_script = f.read()
script.setScript(f"{paho_script}\n{script_text}")

if (client):
    xout = pipeline.create(dai.node.XLinkOut)
    xout.setStreamName('end')
    script.outputs['out'].link(xout.input)

    #  After initializing the device, enable log levels
    device_info = dai.DeviceInfo('192.168.100.37')
    with dai.Device(pipeline, device_info) as device:
        device.setLogLevel(dai.LogLevel.WARN)
        device.setLogOutputLevel(dai.LogLevel.WARN)
        while True:
            print(marshal.loads(device.getOutputQueue("end").get().getData())) # Wait for the "end" msg
else:
    (f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
    bootloader = dai.DeviceBootloader(bl)
    progress = lambda p : print(f'Flashing progress: {p*100:.1f}%')
    bootloader.flash(progress, pipeline)
  • erik replied to this.

    Hi dirkjankrijnders ,
    Did you try to flash any other demo (eg http server) and confirmed that it works as expected?
    Thanks, Erik

    Yes, I have and it works. I modified this "depthai-python/ examples / Script / script_http_server.py" in the same way as the script above. The http server becomes available after I hear the relay click. With my script I do hear the relay click, but I never see messages on the MQTT server.
    Thanks,
    Dirkjan

    • erik replied to this.

      Hi Erik,

      Thanks for looking into this, looking forward to the results.
      Dirkjan

      a month later

      dirkjankrijnders

      I tested with the following app:

      #!/usr/bin/env python3
      
      import depthai as dai
      import time
      
      flashPipeline = False
      
      # Start defining a pipeline
      pipeline = dai.Pipeline()
      
      # Define a source - color camera
      cam = pipeline.create(dai.node.ColorCamera)
      # VideoEncoder
      jpeg = pipeline.create(dai.node.VideoEncoder)
      jpeg.setDefaultProfilePreset(cam.getFps(), dai.VideoEncoderProperties.Profile.MJPEG)
      
      # Define sources and outputs
      imu = pipeline.create(dai.node.IMU)
      
      # enable ROTATION_VECTOR at 400 hz rate
      imu.enableIMUSensor(dai.IMUSensor.ROTATION_VECTOR, 100)
      imu.setBatchReportThreshold(20)
      imu.setMaxBatchReports(20)
      
      # Script node
      script = pipeline.create(dai.node.Script)
      script.setProcessor(dai.ProcessorType.LEON_CSS)
      script.setScript("""
          from http.server import BaseHTTPRequestHandler
          import socketserver
          import socket
          import fcntl
          import struct
      
          PORT = 8080
          ctrl = CameraControl()
          ctrl.setCaptureStill(True)
      
          def get_ip_address(ifname):
              s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
              return socket.inet_ntoa(fcntl.ioctl(
                  s.fileno(),
                  -1071617759,  # SIOCGIFADDR
                  struct.pack('256s', ifname[:15].encode())
              )[20:24])
      
          class HTTPHandler(BaseHTTPRequestHandler):
              def do_GET(self):
                  if self.path == '/':
                      self.send_response(200)
                      self.end_headers()
                      self.wfile.write(b'<h1>[DepthAI] Hello, world!</h1><p>Click <a href="img">here</a> for an image</p>')
                  elif self.path == '/img':
                      node.io['out'].send(ctrl)
                      jpegImage = node.io['jpeg'].get()
                      rv = node.io['quaternions'].get()
                      node.warn(f"got smth")
      
                      self.send_response(200)
                      self.send_header('Content-Type', 'image/jpeg')
                      self.send_header('Content-Length', str(len(jpegImage.getData())))
                      self.end_headers()
                      self.wfile.write(jpegImage.getData())
                  else:
                      self.send_response(404)
                      self.end_headers()
                      self.wfile.write(b'Url not found...')
      
          with socketserver.TCPServer(("", PORT), HTTPHandler) as httpd:
              node.warn(f"Serving at {get_ip_address('re0')}:{PORT}")
              httpd.serve_forever()
      """)
      
      # Connections
      cam.still.link(jpeg.input)
      script.outputs['out'].link(cam.inputControl)
      jpeg.bitstream.link(script.inputs['jpeg'])
      imu.out.link(script.inputs['quaternions'])
      
      if flashPipeline:
          (f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
          bootloader = dai.DeviceBootloader(bl)
          progress = lambda p : print(f'Flashing progress: {p*100:.1f}%')
          bootloader.flash(progress, pipeline)
      
      # Connect to device with pipeline
      with dai.Device(pipeline) as device:
          while not device.isClosed():
              time.sleep(1)

      And IMU works in standalone mode.

      What is the output of running bootloader_version.py ?

      Hi,

      First the bootloader version:
      (venv) PS C:\Data\OakD-Lite> & c:/Data/OakD-Lite/venv/Scripts/python.exe c:/Data/OakD-Lite/depthai-python/examples/bootloader/bootloader_version.py
      Found device with name: 192.168.178.26
      Version: 0.0.24
      NETWORK Bootloader, is User Bootloader: False
      Memory 'Memory.FLASH' size: 16777216, info: JEDEC ID: 01 20 18
      Memory 'Memory.EMMC' size: 15758000128, info:

      Which, according to the device_manager.py, is the latest version.

      And I can confirm that I can run your script in standalone mode as well. I guess the MQTT code is not cooperating, is there any way to debug this?

      When I flash my script, the device keeps rebooting. At least, every now and then the relay clicks. Does that point to something?
      Thanks,

      Dirkjan