Python add-in runs OK in a debug session, but NOK at normal runtime

Python add-in runs OK in a debug session, but NOK at normal runtime

mike46YZU
Contributor Contributor
488 Views
2 Replies
Message 1 of 3

Python add-in runs OK in a debug session, but NOK at normal runtime

mike46YZU
Contributor
Contributor

Hi,


I've got a strange problem. I'm working on an add-in to rotate the view though a serial command. In a debug session my test script runs just fine and it does what it is supposed to do. In the "Scripts and Add-Ins" window in fusion I can then stop the script and close fusion normally.

 

Now when I run that same script normally instead of in a debug session, the script works, but in the "Scripts and Add-Ins" window the Stop button is greyed out. So I cannot stop the script and I cannot close fusion gracefully.

 

I'm hoping to find some help here, here's my script:

 

# Assuming you have not changed the general structure of the template no modification is needed in this file.
import adsk.core, adsk.fusion, traceback, math
import time
import threading

import sys
import os

current_dir = os.path.dirname(os.path.abspath(__file__))
packages_path = os.path.join(current_dir, 'packages')
sys.path.append(packages_path)
import serial
sys.path.remove(packages_path)

# globals
app = None
view = None
camera = None
target = None
up = None
dist = None
ui = None
port_name = None
ser = None

thread = None
# Flag to indicate whether the thread should continue running
keep_running = True
data_available = False
angle = 0


def init():
        global app
        app = adsk.core.Application.get()
        global view
        view = app.activeViewport
        global camera
        camera = view.camera

        global target
        target = adsk.core.Point3D.create(0,0,0)
        global up
        up = adsk.core.Vector3D.create(0,0,1)

        global ui
        ui = app.userInterface
        global port_name
        port_name = "COM10"

        global dist
        dist = camera.target.distanceTo(camera.eye)

        global ser

        try:
            # Try to open the specified COM port
            ser = serial.Serial(port=port_name, baudrate=115200, timeout=2)
            ui.messageBox('Port opened successfully!...')
        except:
            ui.messageBox('Cannot open port...')

def run(context):
    global ui
    global angle
    global data_available
    global keep_running

    try:

        init()

        global thread
        thread = threading.Thread(target=read)
        thread.start()

        while keep_running:
            if data_available == True:
                update(angle)
                data_available = False
            adsk.doEvents()

    except:
        ui.messageBox('Run Error!')

def update(angle):
    global view
    global camera
    global target
    global up
    global dist

    
    camera.target = target
    camera.upVector = up
    
    eye = adsk.core.Point3D.create(dist * math.cos((math.pi*2) * angle/1000), dist * math.sin((math.pi*2) * angle/1000), 10)
    camera.eye = eye

    camera.isSmoothTransition = False
    view.camera = camera
    view.refresh()

def read(): #this method runs in a thread to acquire serial data
    global ser
    global keep_running
    global data_available
    global angle

    while keep_running:
        data = ser.read_until(b'\n')  # Read data until a newline character is encountered
        if data:  # If data is received
            try:
                print(data.decode())
                angle = float(data.decode().strip())  # Convert the ASCII data to a floating-point number
                #print(f"Received floating-point value: {angle}")
                data_available = True


            except ValueError:
                print("Received non-numeric ASCII data")
        adsk.doEvents()


def stop(context):
    app = adsk.core.Application.get()
    ui = app.userInterface
    global ser
    try:
        global keep_running
        keep_running = False  # Set the flag to stop the thread
        thread.join()         # Wait for the thread to finish gracefully
        ser.close()           # close the serial port
        ui.messageBox('Add-in stopped...')


    except:
        ui.messageBox('stop except')
0 Likes
Accepted solutions (1)
489 Views
2 Replies
Replies (2)
Message 2 of 3

Jorge_Jaramillo
Collaborator
Collaborator
Accepted solution

Hi,

 

I believe your problem is a threading issue because the run() function in not finishing to let Fusion 360 do its work to complete the start of the add-in.


In your code you might need to move the while loop to the read() function:

wtallerdemadera_0-1692719966853.png

 

Then you can control all async reading staff within that thread, not inside the Fusion 360's own thread.

That is the reason, I believe, why the close button is grayed out.

 

Regards,

Jorge Jaramillo

Software Engineer

 

Message 3 of 3

mike46YZU
Contributor
Contributor
Thanks, that did the trick!
0 Likes