Serial module not supported by AddIns on Python?

Serial module not supported by AddIns on Python?

vgegok
Contributor Contributor
1,070 Views
4 Replies
Message 1 of 5

Serial module not supported by AddIns on Python?

vgegok
Contributor
Contributor

I created an add-on module to receive posture angles from serial devices (Arduino+MPU6050), but when I added serial-related code to the project, there was no response when I executed the add-on module.
I don't know where to see the error message.
Is serial not supported by add-on modules?


My AddIns code is as follows:

 

 

# Assuming you have not changed the general structure of the template no modification is needed in this file.
import adsk.core
import adsk.fusion
import adsk.cam
import traceback
import threading
import random
import json
import serial
handlers = []


class ThreadEventHandler(adsk.core.CustomEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args):
        try:
            # Make sure a command isn't running before changes are made.
            if ui.activeCommand != 'SelectCommand':
                ui.commandDefinitions.itemById('SelectCommand').execute()

            # Make sure a command isn't running before changes are made.

            eventArgs = json.loads(args.additionalInfo)

            newEye = adsk.core.Point3D.create(float(eventArgs['Roll']), float(eventArgs['Pitch']), 1)
            # newEye = adsk.core.Point3D.create(float(eventArgs['Value']), 0, 1)

            camera.eye = newEye
            app.activeViewport.camera = camera
            # app.activeViewport.fit()
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


class CaptureCamThread(threading.Thread):
    def __init__(self, event):
        threading.Thread.__init__(self)
        self.stopped = event

    def run(self):
        try:
            ser = serial.Serial('COM4', 115200, timeout=1)
            while not self.stopped.wait(2):
                # while(True):
                read = ser.readline()
                read = read.decode()
                if read != '':
                    RollPitch = read.split()
                    # print(type(RollPitch))
                    Roll = float(RollPitch[0])
                    Pitch = float(RollPitch[1])
                    args = {'Roll': Roll, 'Pitch': Pitch}
                    app.fireCustomEvent('CaptureCamThreadID', json.dumps(args))
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def run(context):
    global app
    global ui
    global view
    global camera
    global eye
    try:
        # This will run the start function in each of your commands as defined in commands/__init__.py
        app = adsk.core.Application.get()
        ui = app.userInterface
        view = app.activeViewport
        camera = view.camera
        eye = camera.eye

        global customEvent
        customEvent = app.registerCustomEvent('CaptureCamThreadID')
        onThreadEvent = ThreadEventHandler()
        customEvent.add(onThreadEvent)
        handlers.append(onThreadEvent)

        global stopFlag
        stopFlag = threading.Event()
        myCaptureCamThread = CaptureCamThread(stopFlag)
        myCaptureCamThread.start()

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def stop(context):
    try:
        if handlers.count:
            customEvent.remove(handlers[0])
        stopFlag.set()
        app.unregisterCustomEvent('CaptureCamThreadID')
        ui.messageBox('Stop addin')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

This is a script, Like Addins, I encountered the same problem:

 

 

# Author-vgegok
# Description-

import adsk.core
import adsk.fusion
import adsk.cam
import traceback
import serial
import time

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        view = app.activeViewport
        camera = view.camera
        eye = camera.eye
        for i in range(0, 100):
            ser = serial.Serial('COM4', 115200, timeout=1)
            # while(True):
            time.delay(2)
            read = ser.readline()
            read = read.decode()
            if read != '':
                RollPitch = read.split()
                # print(type(RollPitch))
                Roll = float(RollPitch[0])
                Pitch = float(RollPitch[1])
                newEye = adsk.core.Point3D.create(Roll, Pitch, 1)
                camera.eye = newEye
                app.activeViewport.camera = camera
            # app.activeViewport.fit()
        ui.messageBox(str(eye.x))

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

Some examples can be referred?

 

0 Likes
1,071 Views
4 Replies
Replies (4)
Message 2 of 5

kandennti
Mentor
Mentor

Hi @vgegok .

 

As with general python, if you want to use external modules, you need to install them.
However, since the Fusion360API python is a proprietary environment, it cannot be installed by a simple pip install.

 

The installation of "numpy" is a relatively popular topic in the forum, so please search for "numpy".

0 Likes
Message 3 of 5

vgegok
Contributor
Contributor

Thank you very much. As you know, I successfully installed pyserial and ran Add INS!
However, I have encountered a new problem. When I use pyserial to continuously receive data from the serial port, Fusion 360 may get stuck or crash.

Here is my code:

# Assuming you have not changed the general structure of the template no modification is needed in this file.
import adsk.core
import adsk.fusion
import adsk.cam
import traceback
import threading
import json
import serial
handlers = []


class ThreadEventHandler(adsk.core.CustomEventHandler):
    def __init__(self):
        super().__init__()

    def notify(self, args):
        try:
            # Make sure a command isn't running before changes are made.
            if ui.activeCommand != 'SelectCommand':
                ui.commandDefinitions.itemById('SelectCommand').execute()

            # Make sure a command isn't running before changes are made.

            eventArgs = json.loads(args.additionalInfo)

            newEye = adsk.core.Point3D.create(
                float(eventArgs['Roll']), float(eventArgs['Pitch']), 1)
            # newEye = adsk.core.Point3D.create(float(eventArgs['Value']), 0, 1)

            camera.eye = newEye
            app.activeViewport.camera = camera
            # app.activeViewport.fit()
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


class CaptureCamThread(threading.Thread):
    def __init__(self, event):
        threading.Thread.__init__(self)
        self.stopped = event

    def run(self):
        try:
            ser = serial.Serial('COM4', 115200, timeout=1)
            while not self.stopped.wait(1):
                # Roll = 1
                # Pitch = 0
                # args = {'Roll': Roll, 'Pitch': Pitch}
                # app.fireCustomEvent('CaptureCamThreadID', json.dumps(args))
                ser.reset_input_buffer()
                read = ser.readline().decode()
                if len(read) != 0:
                    RollPitch = read.split()
                    # print(type(RollPitch))
                    Roll = abs(float(RollPitch[0]))
                    Pitch = abs(float(RollPitch[1]))
                    args = {'Roll': Roll, 'Pitch': Pitch}
                    # f.close()
                    app.fireCustomEvent('CaptureCamThreadID', json.dumps(args))
        except:
            if ui:
                ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def run(context):
    global app
    global ui
    global view
    global camera
    global eye
    try:
        # This will run the start function in each of your commands as defined in commands/__init__.py
        app = adsk.core.Application.get()
        ui = app.userInterface
        view = app.activeViewport
        camera = view.camera
        eye = camera.eye

        global customEvent
        customEvent = app.registerCustomEvent('CaptureCamThreadID')
        onThreadEvent = ThreadEventHandler()
        customEvent.add(onThreadEvent)
        handlers.append(onThreadEvent)

        global stopFlag
        stopFlag = threading.Event()
        myCaptureCamThread = CaptureCamThread(stopFlag)
        myCaptureCamThread.start()

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def stop(context):
    try:
        if handlers.count:
            customEvent.remove(handlers[0])
        stopFlag.set()
        app.unregisterCustomEvent('CaptureCamThreadID')
        # ui.messageBox('Stop addin')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
Message 4 of 5

Jorge_Jaramillo
Collaborator
Collaborator

Hi @vgegok ,

 

I believe your blocking Fusion issue is because you are using the ser.readline() in CaptureCamThread.run() method to wait for the input. Since this function blocks the thread, maybe it is not giving enough time to Fusion to run.

 

I'd suggest use an async function to read from the serial port, which won't cause the thread to be blocked (maybe

await asyncio.wait(...) could be used).

I had used that kind of async functions to make inter-process communication, leaving enough CPU time to Fusion without any performance issue.

 

Hope this could help.

 

Regards,

Jorge Jaramillo

 

Message 5 of 5

vgegok
Contributor
Contributor

Okay, thank you for your reply, I will try according to your ideas!

0 Likes