python script partial execute

I’ve got dynamixel SDK python scripts that open a port to a smart servo motor over serial:

dynamixel.openPort(1)

then I want to send out a motor goal position every frame, but I don’t want to open/close port again. I want to keep the port open until I don’t.

dynamixel.write2ByteTxRx(1,2,3,n)

IM assuming i want to write a script in chopExecute or Execute DAT that will allow me to change variable ‘n’. But I don’t understand the basic structure of this scripting. I need an example. Im guessing I turn ‘value change’ toggle on, but where in script does openPort command need to live so it executes only once ?

basically how do i write a script that will open the port once, then change ‘n’ 30fps.
then close the port manually when I want ?

Sounds like you might start by making a toggle button that calls the connect when turned on and disconnect when turned off. Use the panel exec DAT to write callbacks onOffToOn and onOnToOff…

As for sending the values at 30fps there are a few ways, but a simple one is to use executeDAT’s onFrameStart and set the project fps to 30.

Thks Ivan.I think I figured something out.
Not sure if it’s most efficient coding, but it seems to work:

def offToOn(v1, sampleIndex, val, prev):
dynamixel.openPort(port_num)
print(“Succeeded to open the port!”)
return

def whileOn(channel, sampleIndex, val, prev):
return

def onToOff(v1, sampleIndex, val, prev):
dynamixel.closePort(port_num)
print(“Succeeded to close the port!”)
return

def whileOff(channel, sampleIndex, val, prev):
return

def valueChange(channel, sampleIndex, val, prev):

x = int(op('null1')['chan1'])
y = int(op('null1')['chan2'])
p = int(op('null1')['v1'])
dynamixel.write2ByteTxRx(1, 1, 1, ADDR_MX_GOAL_POSITION, x)
dynamixel.write2ByteTxRx(1, 1, 2, ADDR_MX_GOAL_POSITION, y)
print(x)
print(y)
return

what im still not understanding is this code:

def valueChange(channel, sampleIndex, val, prev):

I need an explanation/example of (channel, sampleIndex, val, prev).
I replaced ‘channel’ with ‘v1’ but im not sure that did anything.

I changed values and it seemed to have no effect:
(channel, sampleIndex, valX, prev).

Your onToOff/offToOn code makes sense looking at the CHOP output of the button. The valueChange callback will only be called when the button’s value changes and it looks like you want to send those write2ByteTxRx messages every frame. To do that use the onFrameEnd callback in an executeDAT. That callback will run every frame. And if you need to run at 30fps, you can set that in the bottom left area of the editor by the timeline.

An alternative to using Execute DAT is using a Chop Execute DAT on op(‘null1’) and using the onValueChange callback. That will get called every time the CHOP changes

channel is the CHOP channel whose value changed
sampleIndex is which sample changed (only for multisample CHOPs)
val is the value the channel changed to
prev is the previous value of the channel

I guess I’m not sure exactly how your network is set up, so my suggestions might not make sense. Feel free to attach a tox or toe.

ok so I am not clear on the callbacks scripting structure here still.

My intent:

  1. ‘v1’ and ‘LED’ trigger 2 different actions when either one goes offToOn.
    I scripted ‘v1’ to open/close port, but how now in the same script to turn ‘LED’ off/on ?

  2. ‘variable1’ and ‘variable2’ trigger 2 different actions when either value changes.

What does the script look like ? I’m not sure how to construct this in one CHOPexecuteDAT…
Chopex1.3.toe (4.9 KB)

You just need to test names to figure out what channel is changing.

This code should get you going…

def offToOn(channel, sampleIndex, val, prev):
	channelName = channel.name
	if channelName == 'v1':
		dynamixel.openPort(port_num)
		print("Succeeded to open the port!")
	elif channelName == 'LED':
		debug('do LED')
	
	return

def whileOn(channel, sampleIndex, val, prev):
	return

def onToOff(channel, sampleIndex, val, prev):
	channelName = channel.name
	if channelName == 'v1':
		dynamixel.closePort(port_num)
		print("Succeeded to close the port!")
	elif channelName == 'LED':
		debug('do LED')

thanks Ivan, missed this!