Which functions to call for moves from within python

I am looking for a way to use klipper as a Platform to realize motion Data generated from an external Program in real-time.

The Idea is to have commands coming in through MQTT as json format (mainly containing timestamps and the position for each axis) and handling the realization of these commands .
The kinematics will be none as there will just be a bunch of independent steppers as a generic drive (the plan is to be highly scalable and potentially drive thousands of motors) connected via network.

For this use case the klippy.py main entry point seems like a logical point to include a custom class for the conversion into python calls. So probably the main printer object would need to be passed into this class.

My question is, which functions would need to be called inside this new class to realize a single move (preferrably to be set in mm) at the time set in the timestamp in the MQTT message?
Is there a way to get the current status (MCU connection and positions of the axes) from the Printer Object?

I might be reading this wrong, are you trying to pull Klipper into your existing project? Or use Klipper and expand it for your project?

Klipper requires a lot of different files to run right, you really won’t get by without using the entire source code. Once you get a better grasp on the entire system you can start paring down on files in the "extras’ folder but you’ll probably still need a few of them at least.

As for movements.

Once Klipper is running:

toolhead = self.printer.lookup_object('toolhead')
toolhead.manual_move([x_coord,y_coord,z_coord],move_speed)

Highly recommend reading the developer docs

https://www.klipper3d.org/Code_Overview.html

There are quite a few discussions about with similar intentions and typically exactly this “real-time” is the dead end for it.
Klipper does not process motion data in real-time, but it tries to buffer a queue of >2s, which virtually cannot be modified until fully executed.

Thanks for the replies.

I am trying to expand Klipper to receive the externally generated Data and move accordingly

Do I understand correctly that I should implement this code rather as a host module instead of modifying the main entry point?

Is it also possible to move only specific axes or do I need to specify the coordinates for all axes in every call?

Yes, All addons to klipper should be a host module. I wouldn’t mess with the original Klipper code unless you have a very strong reason to. Again, Check out the Development docs I linked above, It goes into exactly how to add a host module in and get Klipper to recognize it.

Important point though, Unless you have the same host module referenced in your cfg files somewhere it’ll skip right over it.

In other words, If you add a new module named “myproject.py” with a class inside it called “class myproject:”

Unless you add

[myproject]

in your cfg file somewhere, Klipper won’t parse the file. You don’t even really have to have anything under it if for some reason you don’t want to. But it has to be there.

Is it also possible to move only specific axes or do I need to specify the coordinates for all axes in every call?

As far as I remember you have to specify, but what you can do make a little helper function.

def ez_move(self, axis, distance, speed):
   axis_lookup = {'X': 0, 'Y': 1, 'Z': 2}

   if axis not in axis_lookup:
      return
   pos = toolhead.get_position() #contains current x,y,z position
   pos[axis_lookup[axis]] += distance #increment/decrement axis by distance
   toolhead.manual_move(pos, speed)

I’d probably add in a check to make sure distance is a number.
You might not even need the speed part if you plan on making all moves at the same speed.

Axis_lookup might be better as a constant as well but that’s up to you. I’m not sure the best practices for Python in that regard as it’s not my language of choice.

If you are going to make all your moves at the same speed then I’d definitely make that a const and just use that like

MOVE_SPEED = 30

and then

toolhead.manual_move(pos, MOVE_SPEED)

Huge thanks again for the quick reply.

Then I will implement the code as a module.

1 Like