Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using of ringbuffers in servo-thread #475

Closed
luminize opened this Issue Feb 2, 2015 · 5 comments

Comments

Projects
None yet
2 participants
@luminize
Copy link
Member

luminize commented Feb 2, 2015

@mhaberler
I would like to experiment with delaying signals for a certain period of time.

Because of lag behaviour of an extruder, I'd like to see if putting motion commands in a buffer will buy time to influence the extruder output. So instead of a motion look-ahead (something difficult) i'd like to put a delay between motion pins and the stepgen pins without losing the values. Resulting in delayed joints motion, and an non-delayed extruder motor.

I got this idea from PCW mentioning making a simple HAL component which delays motion for a period of time, like so:

# position command and feedback
net emcmot.00.pos-cmd <= axis.0.motor-pos-cmd
net emcmot.00.pos-cmd => delay.0.in
net delayed-00-pos-cmd <= delay.0.out
net delayed-00-pos-cmd => some-driver.stepgen.00.position-cmd

Suppose that this works, to delay with max 0.5 seconds on a servo-thread of 70000 ns I need an array per joint with a size of (0.5s / 70000 ns) = 7143 values. That's not a simple HAL component anymore.

Seeing that there is already a ring buffer component in machinetalk I would be bonkers if I do not try to use something that's almost all I need.

I would initiate/enable it in the following way:

  • when delay.0 is disabled, delay.0.out equals delay.0.in because the reading pointer equals the writing pointer.
  • specify a delay (say delay=10 (servo-thread periods)) before enabling.
  • When enabling this component this functionality should make sure the reading pointer equals the writing pointer and will first wait delay periods before increasing, thus not feeding the stepgen with illogic positions.

when delaying:

  • get the current position-cmd into ringbuffer[current]
  • read the delayed position-cmd of ring buffer[(current-delay)]
  • the signal then passes that position-cmd into the stepgen
  • after use, when disabling the delay.0 the reading pointer should increment delay periods while the reading pointer doesn't. thus feeding the last delayed positions into the stepgen. When the pointers ate equal and don't then again delay.0.out equals delay.0.in

Would you see above way of working with the ringbuffer and its size possible? Or is it better to define an array inside the to-be-written component?

@luminize luminize added the question label Feb 2, 2015

@mhaberler

This comment has been minimized.

Copy link
Member

mhaberler commented Feb 2, 2015

yeah, why not.

I guess you'd need edge detection on the enable in, then starting a counter on each cycle which clocks in samples
you'd start clocking out samples after the thresold is reached

if enable goes negative, you'd continue clocking out samples until the ring is empty

In your case the ring would be internal to the comp I guess
see the example comps in https://github.com/machinekit/machinekit/tree/master/src/machinetalk/msgcomponents - drop me a note if you get stuck

what you want is a 'record mode' ring - the ringbuffer has supports records and carries a size field for each record
probably the record is just an array of HAL_FLOATS ?

for edge detection, see the enable pin and the last_enable tracking variable use in http://git.mah.priv.at/gitweb?p=emc2-dev.git;a=blob;f=src/hal/components/mvjun.comp;h=bf9b6106fbd679abe46a18b4b4e6e3238ce292be;hb=bd873dc4cb3bc4b021a0225aace0d976a23db9e7#l88

note that you can iterate over a buffer's contents even while records are written (the iterator works from a ring snapshot, aka 'generation'), see hal_iter.c/.h - this might be relevant when inspecting the delay line contents

@mhaberler

This comment has been minimized.

Copy link
Member

mhaberler commented Feb 20, 2015

Bas and me have been conspiring for a while on a delayline component which can delay an arbitrary number of float pins for an arbitrary number of periods

it's the first usable "user" application of a HAL ringbuffer, and written such that:

  • another RT component could inspect the delay line contents between the sample and output thread functions
  • samples could also be fed from a userland component and with a bit of cython also from Python, replacing the sample thread function and feeding arbitrary values at arbitrary times to the HAL pins
  • or it could be used the other way round - sampling in RT and processing in userland

this might evolve into an eventual successor to halsampler/halstreamer

first glimpse of delay in action: http://static.mah.priv.at/public/delayline.jpg

branch https://github.com/mhaberler/machinekit/commits/delayline-cleaned - with educational-level commenting

for an inspector setup you would have something like:

loadrt delayline names=foo delay=500,2500 samples=2 # creates the foo.samples ringbuffer
loadrt inspector rb=foo.samples # attaches to the foo.samples ring (R/O)

addf foo.sample servo
addf inspector.inspect servo # has access to the current delay line contents, and can iterate over samples
addf foo.output servo

@luminize

This comment has been minimized.

Copy link
Member Author

luminize commented Feb 21, 2015

I succesfully wired the component to the stepgen, resulting in picture below. the yellow line is the delayed speed going into the join.n, the red line comes out of axis.n
screenshot

@mhaberler

This comment has been minimized.

Copy link
Member

mhaberler commented Feb 21, 2015

super!

@luminize

This comment has been minimized.

Copy link
Member Author

luminize commented Mar 5, 2015

#520 just got merged, closing this question

@luminize luminize closed this Mar 5, 2015

zultron added a commit to zultron/machinekit that referenced this issue Jul 31, 2018

zultron added a commit to zultron/machinekit that referenced this issue Jul 31, 2018

zultron added a commit to zultron/machinekit that referenced this issue Jul 31, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.