#emc-devel | Logs for 2006-09-27

[00:42:29] <jepler> jmkasunich: userspace can't call rtapi_task_resume()? What a pity.
[00:43:28] <jmkasunich> you want to sleep a RT task and wake it up when userspace needs it?
[00:43:38] <jepler> yes basically
[00:43:59] <jmkasunich> what are you trying to do?
[00:44:07] <jepler> it's a secret
[00:44:21] <jmkasunich> obviously not something that requires periodic RT stuff
[00:44:27] <jepler> I want to implement 'newinst': create an instance of a loaded RT component with a given prefix
[00:44:42] <jmkasunich> oh
[00:45:07] <jmkasunich> same trick would let you do newthread and a number of other nice things
[00:45:08] <jepler> one step of that is to have userspace kick off the running of the realtime code that actually does it
[00:45:34] <jmkasunich> yeah
[00:46:13] <jmkasunich> "realtime" is actually a misnomer, you just want to invoke some kernel space code, and don't really care how long it takes
[00:46:19] <jepler> sure
[00:46:32] <jmkasunich> I've thought about that a lot... and so far no elegant answers
[00:47:16] <jmkasunich> test
[00:47:21] <jmkasunich> /proc entries would let userspace invoke some kernel code
[00:47:47] <jmkasunich> duh, leading slashes don't work (but don't complain either, I wonder what I just changed)
[00:49:12] <jmkasunich> if the idea of putting parsing and such in kernel space didn't make me retch, I'd be tempted to do something like "echo newinst foo bar blat" >/proc/hal
[00:50:21] <jmkasunich> ioctls are another approach
[00:51:12] <jmkasunich> do the parsing in user space, then issue ioctls to /dev/hal or something similar to invoke the kernel code
[01:00:30] <jepler> so it is necessary to create the fastest thread first?
[01:00:54] <jmkasunich> yes, because it sets the timer period
[01:01:06] <jmkasunich> all others run at multiples of the timer period
[01:01:35] <jmkasunich> I suppose you could stop the timer and restart it if you needed a faster thread, but it would get _very_ complex, and dangerous if the machine is already running
[01:23:12] <jepler> well that didn't work too well
[01:23:33] <jmkasunich> what did you try?
[01:24:24] <jepler> creating the task, and calling rtapi_task_resume(constructor_task_id) from thread_task
[01:24:28] <jepler> it just hard locked, no messages
[01:24:56] <jepler> is it OK or wrong to call rtapi_mutex_get() from there?
[01:25:31] <jepler> in constructor_task, a "free-running" task
[01:25:40] <jmkasunich> wrong I think, but unless somebody else was holding the mutex thats not the problem
[01:25:46] <jepler> halcmd probably is
[01:25:50] <jepler> it sets this pointer and then releases the mutex
[01:26:10] <jepler> and constructor_task is resumed when the pointer is seen to be non-NULL
[01:26:30] <jmkasunich> then its unlikely that halcmd had the mutex
[01:26:58] <jmkasunich> the delay between pointer set and mutex release is probaly sub-microsecond (unless you do other stuff inbetween)
[01:27:23] <jmkasunich> lemme understand what you are doing:
[01:27:32] <jmkasunich> you have a periodic task (hal thread), right?
[01:27:54] <jmkasunich> then you create a freeruning task, and the periodic one will call resume on the freerunning one?
[01:27:54] <jepler> yes
[01:28:11] <jepler> thread_task is the existing one in hal_lib
[01:28:31] <jepler> if (hal_data->pending_constructor) {
[01:28:31] <jepler> rtapi_task_resume(hal_data->constructor_task_id);
[01:29:16] <jepler> perhaps I should just give up on shoehorning this into tasks
[01:29:20] <jepler> and do something else
[01:29:37] <jmkasunich> If resume is busted, I'd like to fix it
[01:30:16] <jmkasunich> to make the constructor task you called rtapi_task_new, right?
[01:30:27] <jepler> yes
[01:30:33] <jepler> let me take out the calls to mutex_get
[01:30:42] <jepler> basically make it do nothing but print a message
[01:30:47] <jmkasunich> good test
[01:30:47] <jepler> and see if it locks up or not
[01:30:54] <jmkasunich> the get was in the constructor task?
[01:33:20] <jepler> yes
[01:33:33] <jmkasunich> what is the priority of the contstructor task compared to the periodic task(s)?
[01:33:40] <jmkasunich> it should be lower I think
[01:34:26] <jepler> [ 268.182618] HAL: constructor task running, f1cfe0fe test
[01:34:38] <jepler> ok this much is fine
[01:35:11] <jmkasunich> I'd suggest that the thread_task do this:
[01:35:26] <jmkasunich> if (hal_data->pending_constructor) {
[01:35:54] <jepler> hal_data->constructor_task_id = rtapi_task_new(constructor_task,
[01:35:54] <jepler> NULL, rtapi_prio_lowest(), lib_module_id, HAL_STACKSIZE, RTAPI_USES_FP);
[01:36:18] <jmkasunich> if ( rtapi_mutex_try(mutex) == 0 ) {
[01:36:48] <jmkasunich> rtapi_task_resume(hal_data->constructor_task_id);
[01:36:51] <jmkasunich> }
[01:36:52] <jmkasunich> }
[01:37:11] <jmkasunich> then the constructor can assume that it already has the mutex when it wakes up
[01:37:23] <jmkasunich> make sure it releases the mutex before it goes back to sleep
[01:37:52] <jmkasunich> if somebody else has the mutex when the pointer becomes non-null, the resume will just be delayed
[01:39:08] <jepler> I'll leave the mutex issue alone for a moment, and see if I can figure out why only one 'newinst' works with the do-nothing code in constructor_task
[01:39:37] <jmkasunich> ?
[01:40:16] <jepler> 'newinst wcomp test1; newinst wcomp test2' hangs because userspace is waiting for the pointer to be zero'd by the kernel
[01:40:48] <jmkasunich> the kernel code is supposed to zero the pointer when its finished?
[01:41:08] <jepler> yes, that's how userspace knows it's done
[01:41:17] <jmkasunich> what exactly is the pointer pointing at anyway?
[01:41:31] <jepler> a function registered by the component and stored in the component structure
[01:41:38] <jmkasunich> you can't pass pointers from user space to kernel space (maybe you already know that)
[01:41:54] <jepler> it's used in an opaque fashion by userspace
[01:42:21] <jmkasunich> so the constructor task only cares if its NULL or not?
[01:42:25] <jmkasunich> that should be ok
[01:43:25] <jmkasunich> lemme make sure I understand:
[01:43:30] <jmkasunich> userspace sets a pointer
[01:43:46] <jmkasunich> thread_task sees it set, and does a resume on constructor_task
[01:44:22] <jmkasunich> constructor_task sets the pointer to NULL and calls rtapi_task_pause on itself
[01:44:27] <jmkasunich> and then you do it all again
[01:44:34] <jmkasunich> except the 2nd time fails
[01:44:41] <jmkasunich> right?
[01:44:57] <jepler> yes
[01:45:39] <jmkasunich> and you know that the pointer isn't getting nulled out?
[01:45:56] <jepler> http://pastebin.ca/183624
[01:46:19] <jepler> userspace loops, printing "Waiting for pending_constructor to become NULL (after)
[01:47:23] <jepler> the second time, not the first
[01:47:52] <SWPadnos> do you need some SHMPTR or SHM_OFFSET in there?
[01:48:04] <SWPadnos> (or whatever they actually are)
[01:48:31] <jmkasunich> this is in kernel space: hal_data->constructor_prefix[0] = 0;
[01:48:48] <jmkasunich> but constructor_prefix is a user space pointer
[01:49:05] <jepler> constructor_prefix is an array
[01:49:23] <jmkasunich> its an array in user space (or maybe even in hal shmem)
[01:49:43] <jmkasunich> either way, the address of the array is the address that user space sees it at, not the address that kernel space sees it at
[01:50:01] <jmkasunich> just comment it out - its irrelevant to the problem at hand
[01:50:02] <jepler> [ 1278.100551] HAL: constructor task running, f1cfe0fe test1
[01:50:22] <jepler> it prints just fine with rtapi_print_msg
[01:50:23] <jmkasunich> hmm
[01:50:26] <jmkasunich> * jmkasunich thinks
[01:50:27] <jepler> but I'll comment it out anyhow
[01:50:39] <jepler> I think it's OK because it's an array -- just a bunch of consecutive addresses inside hal_data
[01:50:48] <jmkasunich> duh
[01:50:59] <jmkasunich> the array itself is part of the hal_data struct?
[01:51:03] <jmkasunich> then its find
[01:51:04] <jmkasunich> fine
[01:51:14] <jmkasunich> I thought it was a pointer to an array declared elsewhere
[01:51:22] <jmkasunich> never mind ;-)
[01:53:04] <jmkasunich> the pointer _does_ get zeroed the first time, right?
[01:53:27] <jmkasunich> but the constructor task never runs at all the second time (no "constructor task running")?
[01:54:41] <jepler> yes
[01:54:43] <jepler> userspace prints:
[01:54:43] <jepler> Constructing: wcomp test1
[01:54:44] <jepler> Waiting for pending_constructor to become NULL (after)
[01:54:44] <jepler> Constructing: wcomp test2
[01:54:46] <jepler> Waiting for pending_constructor to become NULL (after)
[01:55:00] <jepler> the last line in dmesg is:
[01:55:00] <jepler> [ 1636.748515] HAL: constructor task running, f1ccb0fe test1
[01:55:07] <jmkasunich> why does the first print say (after)
[01:55:16] <jmkasunich> the first one in the pastebin doesn't
[01:55:31] <jepler> the first one is not usually hit
[01:55:42] <jmkasunich> because its already finished?
[01:55:45] <jepler> only if a competing halcmd set the pointer and it hasn't been cleared by the kernel task
[01:56:06] <jmkasunich> ok, got it
[01:56:26] <jepler> if this is too clever by half, feel free to say it
[01:56:37] <jmkasunich> and the next to last dmesg line is _not_ another hal message?
[01:57:08] <jmkasunich> never mind, its not - the last line says test1, not test2
[01:57:26] <jmkasunich> so the problem isn't that the task isn't clearing the pointer the 2nd time, its not running at all the 2nd time
[01:57:30] <jmkasunich> two things to do:
[01:57:45] <jmkasunich> put a rtapi_print in thread_task, right before the resume
[01:58:13] <jmkasunich> and change rtapi_task_pause(self) to rtapi_task_pause(hal_data->constructor_task_id)
[01:59:02] <jmkasunich> (just in case self doesn't work right - I don't think its used by emc, and could have bitrot
[01:59:06] <jepler> OK
[01:59:12] <jepler> btw, I just checked that the thread is still running
[01:59:20] <jepler> using charge-pump and verifying in halcmd show that it is toggling
[01:59:29] <jmkasunich> ok, thats good
[02:01:25] <jepler> hal_data->pending_constructor = 0;
[02:01:25] <jepler> rtapi_print_msg(RTAPI_MSG_INFO, "HAL: constructor pausing, %d %d\n", rtapi_task_self(), hal_data->constructor_task_id);
[02:01:28] <jepler> rtapi_task_pause(rtapi_task_self());
[02:01:29] <jepler> [ 2056.393473] HAL: constructor task running, f1ccd0fe test1
[02:01:31] <jepler> rtapi_print_msg(RTAPI_MSG_INFO, "HAL: constructor resumed, %p %s\n", hal_data->pending_constructor, hal_data->constructor_prefix);
[02:01:34] <jepler> [ 2056.393484] HAL: constructor pausing, 1 1
[02:01:37] <jepler> jepler@sofa:~$
[02:01:44] <jepler> so task_self() works OK
[02:02:04] <jepler> but it never returns from task_pause()
[02:03:07] <jmkasunich> not even after the next newinst command?
[02:03:26] <jepler> no
[02:04:01] <jepler> if (hal_data->pending_constructor) {
[02:04:01] <jepler> rtapi_print_msg(RTAPI_MSG_INFO, "calling resume(%d)\n", hal_data->constructor_task_id);
[02:04:04] <jepler> rtapi_task_resume(hal_data->constructor_task_id);
[02:04:05] <jepler> [ 2239.507664] calling resume(1)
[02:04:06] <jepler> [ 2239.517663] calling resume(1)
[02:04:06] <jepler> [ 2239.527659] calling resume(1)
[02:04:37] <jmkasunich> ad nauseam....
[02:04:39] <jepler> yes
[02:05:16] <jmkasunich> cat /proc/rtapi/tasks
[02:05:18] <jepler> let's see if task_resume is giving an error
[02:05:22] <jmkasunich> see what state the tasks are in
[02:05:28] <jepler> ******** RTAPI TASKS ********
[02:05:28] <jepler> ID Own Prio State Code
[02:05:28] <jepler> 01 01 4095 FREE RUN f1ce65fd
[02:05:28] <jepler> 02 01 1 PERIODIC f1ce6524
[02:05:52] <jmkasunich> I found the bug
[02:05:52] <jepler> [ 2393.857486] calling resume(1) -> -3
[02:06:28] <jmkasunich> in rtapi_task_pause, I call the RTOS to pause the task, then change its state
[02:06:45] <jmkasunich> well, if I'm pausing myself, I never change the state from FREERUN to PAUSED
[02:06:49] <jepler> ah
[02:06:57] <jmkasunich> and therefore when you call resume, it says "its already running you dummy"
[02:07:11] <jmkasunich> line 877 in rtai_rtapi.c
[02:07:24] <jmkasunich> move it above the call to rt_task_suspend
[02:08:18] <jepler> Constructing: wcomp test1
[02:08:18] <jepler> Waiting for pending_constructor to become NULL (after)
[02:08:18] <jepler> Constructing: wcomp test2
[02:08:18] <jepler> Waiting for pending_constructor to become NULL (after)
[02:08:18] <jepler> jepler@sofa:~/emc2$
[02:08:32] <jmkasunich> that means its happy?
[02:08:43] <jepler> yes
[02:08:51] <jepler> the task successfully runs and clears the pointer twice
[02:08:55] <jmkasunich> yay
[02:09:04] <jmkasunich> you want me to commit the rtapi fix?
[02:09:16] <jmkasunich> its probably also busted on the rtlinux version, I'll check them both
[02:09:52] <jepler> http://pastebin.ca/183639
[02:09:54] <jepler> here's what I wrote
[02:10:04] <jepler> I delared 'oldstate' of course
[02:10:22] <jepler> though what the state would be on the failure of rt_task_suspend, I'm not sure...
[02:10:53] <jmkasunich> oldstate is as good a guess as any - glad you noticed that, I forgot about the fail case
[02:11:10] <jepler> I'll commit this, then
[02:11:18] <jmkasunich> the second "state = PAUSED" is redundant I think
[02:11:31] <jmkasunich> actually, its worse, it just wrong
[02:11:50] <jmkasunich> if you are suspending yourself, by the time you get there you are running again
[02:12:46] <jepler> it's a "-" line
[02:12:51] <jepler> in the diff
[02:12:57] <jepler> (that was a diff fragment)
[02:12:59] <jmkasunich> duh
[02:13:11] <jmkasunich> I thought it was just the code, overlooked the + and -
[02:13:39] <jmkasunich> * jmkasunich can be dense sometimes
[02:17:46] <jepler> holy crap it works
[02:18:12] <jmkasunich> yay!
[02:18:17] <jepler> Component Pins:
[02:18:17] <jepler> Owner Type Dir Value Name
[02:18:17] <jepler> 04 float IN 0.00000e+00 test1.in
[02:18:17] <jepler> 04 bit OUT FALSE test1.out
[02:18:17] <jepler> 04 float IN 0.00000e+00 test2.in
[02:18:20] <jepler> 04 bit OUT FALSE test2.out
[02:19:19] <jmkasunich> it works as long as you have at least one thread defined
[02:19:46] <jepler> yeah
[02:19:49] <jepler> which is a bit dumb
[02:20:08] <jepler> anything would be better than this way of calling the code
[02:20:16] <jmkasunich> I wonder if a semaphore would work?
[02:20:40] <jepler> hm it will create a new instance of a singleton, which may not be what you want
[02:20:54] <jepler> how would I use a semaphore?
[02:21:02] <jmkasunich> crap: NOTE: These semaphore related functions are only available in
[02:21:02] <jmkasunich> realtime modules. User processes may not call them!
[02:22:03] <jmkasunich> I think RTAI semaphores actually _do_ work across the user/RT boundary
[02:22:12] <jmkasunich> but RTLinux's don't, so rtapi's don't
[02:23:33] <jepler> I could do the /proc or ioctl route too
[02:23:54] <jepler> I thought when I started that a task communicating through HAL's shared memory block would be "easiest" but that may not have been the case
[02:24:10] <jepler> or I could add a check in 'newinst' that at least one thread exists, and check it in
[02:25:06] <jmkasunich> dunno
[02:25:31] <jmkasunich> it would be nice to have a better way to invoke kernel code from user space than relying on what is basically polling
[02:25:58] <jmkasunich> newinst is just one place where we want it
[02:26:02] <jmkasunich> newthread is another
[02:26:41] <jepler> though if thread's newinst handler doesn't mind a bit of parsing: newinst thread another-thread:100000000
[02:28:28] <jmkasunich> one of my goals for the elusive "refactor" was to get a lot of the metadata (like component names) out of shared memory an in normal kernel space memory. that means most (all?) hal commands would be implemented in hal_lib.ko only, and the user space hal_lib would just invoke the kernel code to do the work
[02:30:02] <jmkasunich> the "another-thread" thing is just a way to implement newthread?
[02:30:19] <jepler> another-thread would be the thread name
[02:30:23] <jmkasunich> right
[02:30:35] <jmkasunich> you still have to create the first thread the old way
[02:30:40] <jepler> yes
[02:30:54] <jepler> until we replace the halcmd/kernel communication method with something different
[02:31:03] <jmkasunich> yeah
[02:31:05] <jepler> here's the full diff if you care to read it: http://emergent.unpy.net/index.cgi-files/sandbox/newinst.patch
[02:33:34] <jepler> I think that the value of having this now might outweigh it being a little bit gross. I don't see that the external API (namely, halcmd newinst and hal_set_constructor) would need to change if the implementation was changed to use ioctl() or /proc
[02:34:14] <jmkasunich> if we do this for real, the "count" insmod parameter would go away, and loadrt would _not_ install any instances at all, it would only load the module
[02:34:41] <jmkasunich> although we might retain it for a while for compatibility
[02:34:57] <jmkasunich> hmm, the constructor can only create one kind of instance, right?
[02:35:15] <jmkasunich> so you can't have a blocks style module that has multiple things in it
[02:35:19] <jepler> yes
[02:35:42] <jepler> that is true
[02:35:59] <jmkasunich> I haven't read the whole diff yet, but its easier to ask you...
[02:36:30] <jmkasunich> if you say newinst ddt, does it look up the component that contains "ddt" and call that constructor?
[02:36:38] <jepler> right
[02:37:31] <jepler> maybe newinst should support a second argument: newinst parport "i 0x378"
[02:37:33] <jmkasunich> what list does it look "ddt" up in?
[02:37:36] <jepler> the component list
[02:37:57] <jmkasunich> duh, ok
[02:37:58] <jepler> so my above example should be: newinst hal_parport "i 0x378"
[02:38:11] <jmkasunich> the blocks.c model had me screwed up
[02:38:38] <jepler> er
[02:38:51] <jmkasunich> I was thinking that "loadrt blocks" would say "you now have constructors for the following 20 things"
[02:38:52] <jepler> newinst hal_parport primary_port "i 0x378"
[02:39:02] <jepler> while I'm in 'comp' mode
[02:39:09] <jmkasunich> and then later "newinst thing" would get you one of them
[02:39:12] <jepler> one module, one hal component, one type of thing
[02:39:25] <jmkasunich> that probably is good
[02:39:38] <jmkasunich> I'm just trying to see if there are any cases where it causes trouble
[02:40:18] <jmkasunich> passing args to newinst is definitely important
[02:40:34] <jmkasunich> I'd like to replace, not duplicate, the insmod parameters
[02:41:12] <jmkasunich> although that means doing manually a lot of stuff that insmod does for us for free
[02:41:52] <jepler> that gets tough, because passing anything besides a fixed argument list is not something C is designed to do
[02:42:39] <jmkasunich> you almost need a list of "instance arguments"
[02:43:33] <jmkasunich> I guess my thoughts on this are 'commit it, but don't change any sample configs to use it, and consider it a "alpha test" feature, subject to significant change'
[02:43:55] <jmkasunich> we're gonna want to figure out how do to "delinst"
[02:44:11] <jepler> I'll check this in tomorrow
[02:44:16] <jmkasunich> ok
[02:44:18] <jepler> at least, not tonight
[02:44:19] <jepler> goodnight...
[02:44:26] <jmkasunich> goodnight
[02:44:37] <jepler> think about this: is a single argument, passed as a string, a 90% solution?
[02:44:48] <jmkasunich> have to ponder that
[02:44:49] <jepler> constructor(char *instance_name, char *extra_arg)
[02:45:04] <jmkasunich> I think the arrays can go away, because they are usually for per-instance data
[02:45:27] <jmkasunich> strings certainly can be made to work, at the expense of putting parsing code in the components
[02:46:19] <jmkasunich> I think we probably want the hal command to be "newinst <instance_type> <instance_name> <args>"
[02:47:00] <jmkasunich> if type is "ddt", name can be "ddt2", but it can also be "Xvel-ddt" or "foobar"
[02:47:19] <jmkasunich> then delinst would be "delinst <instance_name>"
[02:47:40] <jmkasunich> and the pins, etc, would be <instance_name>.<whatever>
[02:48:51] <jmkasunich> enought for tonight - plenty to think about
[02:48:56] <jmkasunich> and great progress!
[14:51:11] <SWPadnos> ok
[14:51:13] <alex_joni> SWPadnos: basicly .. yes
[14:51:25] <alex_joni> saving on shutdown, restoring on the next startup
[14:51:43] <alex_joni> seems like a nice thing for people without home switches
[14:51:47] <SWPadnos> I thought the variables #5000-#5005 (or somewhere around there) were meant for this
[14:51:59] <SWPadnos> I think there may be something in the spec, actually
[14:52:01] <alex_joni> * alex_joni needs to read the FM
[14:53:31] <cradek> you could do this without breaking ngc compatibility by using #5401 to 5406
[14:53:41] <SWPadnos> I can't remember what doc has the VAR file layout
[14:53:47] <SWPadnos> oh -0 are those the ones?
[14:53:52] <alex_joni> http://www.linuxcnc.org/docs/html/gcode/main/index.html
[14:53:57] <cradek> some parts of the spec say the numbers are 1-5399 and some say 1-5400
[14:54:08] <cradek> http://www.isd.mel.nist.gov/personnel/kramer/pubs/RS274NGC_3.web/RS274NGC_33a.html#1008244
[14:54:22] <alex_joni> cradek: there are already some vars for different homes
[14:54:30] <cradek> yes for g28 and g29
[14:54:42] <cradek> but you can't use those for this
[14:54:44] <alex_joni> g28, g30
[14:54:49] <cradek> err yeah
[14:55:03] <alex_joni> although I have nfc now what g28 & 30 are :)
[14:55:20] <alex_joni> anyways.. would you think it's a good idea?
[14:55:28] <cradek> they are home positions in world coordinates that you can go to with those gcodes
[14:55:33] <alex_joni> 1. add a ini entry to switch the option on
[14:55:41] <alex_joni> 2. save to var and restore from now on
[14:55:54] <cradek> yes
[14:56:14] <cradek> if you enlarge var and use >#5400 for this new thing, so as to not break compat with ngc
[14:56:21] <alex_joni> sure
[14:56:34] <alex_joni> maybe even allow it to read var files which are shorte?
[14:56:42] <cradek> it already can
[14:56:53] <alex_joni> like I said.. never touched the var part :)
[14:56:53] <cradek> a var file does not have to have all the lines
[14:57:07] <cradek> it has to have only a small subset
[14:57:17] <alex_joni> right..
[14:57:28] <cradek> I think this would be great, I missed it when I started using emc
[14:57:54] <cradek> and it might not be too hard since we already have saved state
[14:57:59] <alex_joni> right
[14:58:01] <cradek> brb
[14:58:16] <alex_joni> the only thing I'm worried is getting motion to accept a predefined position from the outside
[14:59:43] <alex_joni> * alex_joni takes a plunge into the code
[15:28:11] <cradek> "Any parameter included in the file read by the Interpreter will be included in the file it writes as it exits."
[15:28:20] <cradek> that's interesting
[15:29:47] <cradek> and against all odds that's actually how it still works
[15:30:29] <SWPadnos> cool: http://www.directencoders.com/shopsite_sc/store/html/ph_phd_estop.html
[15:31:11] <cradek> neat
[15:31:17] <SWPadnos> sorry I left there - I got 3 phone calls :(
[15:32:06] <alex_joni> cradek: yup
[15:32:24] <alex_joni> cradek: the interp will be the easy part
[15:32:34] <SWPadnos> it must be possible - homing needs that functionality
[15:33:13] <alex_joni> SWPadnos: I hear you :)
[15:36:12] <cradek> SWPadnos: that would be a really great pendant for emc
[15:36:26] <jepler> when the interpreter starts, it makes some canon calls to find out the current machine position
[15:36:39] <alex_joni> jepler: yes it does
[15:36:48] <alex_joni> I'm adding canon calls to set position
[15:37:04] <alex_joni> so it will set first, then use the current calls to get the current position
[15:37:27] <alex_joni> otherwise the positions will be overwritten on the next synch()
[15:38:50] <SWPadnos> cradek, that was my thought
[15:39:08] <SWPadnos> though they don't mention what connector is at the end of that nice 16-ft cable
[15:39:24] <cradek> no, but it looks like it has lots of wires
[15:39:27] <jepler> it looks nice but it's not cheap
[15:39:37] <SWPadnos> 25 wires, I think
[15:39:55] <SWPadnos> it may be a DB connector, but then again it may be a circular MS connector (=$$$)
[15:40:28] <jepler> http://emergent.unpy.net/index.cgi-files/sandbox/newinst.patch
[15:40:30] <jepler> oops
[15:40:30] <alex_joni> hmm.. I remember talking to someone about this one
[15:40:51] <alex_joni> I think it was in #emc
[15:40:55] <jepler> the PDF file says what the 25 signals are, and gives wire colors: http://www.koyoencoder.com/products/pdf/phd_estop.pdf
[15:41:25] <SWPadnos> I noticed that, but didn't see anything telling what the connector is
[15:41:37] <SWPadnos> and they cleverly leave it out of the photos ;)
[15:41:46] <cradek> maybe it doesn't have a connector
[15:41:54] <SWPadnos> could be
[15:42:12] <cradek> the wire looks like a 5-wire keyboard wire, hard to believe there are 25 wires
[15:42:37] <SWPadnos> from the drawings, it looks like the wirs is ~20mm diameter
[15:42:39] <SWPadnos> wire
[15:42:48] <cradek> oh ok
[15:44:03] <SWPadnos> it just looks like about half of the vertical 40mm dimension
[15:45:55] <alex_joni> cradek: do you remember what tpSetPos() does?
[15:45:56] <cradek> on page 2 of the pdf I think it looks like 6-8 mm
[15:46:20] <cradek> alex_joni: no, not without digging
[15:46:26] <alex_joni> ok :(
[15:47:06] <alex_joni> ok, found out
[15:52:09] <alex_joni> eek.. this is harder than I thought
[15:52:16] <alex_joni> especially for non-trivkins machines
[15:54:42] <jepler> oh hey I was just saying that to chris, about non-trivial machines
[15:55:24] <cradek> jepler says using the interpreter and varfile is the wrong approach
[15:55:38] <alex_joni> I can see that for non-triv machines
[15:55:39] <jepler> $ patch -p0 < newinst.patch
[15:55:40] <jepler> patching file src/hal/hal.h
[15:55:53] <jepler> oops
[15:55:55] <alex_joni> jepler: ?
[15:55:56] <alex_joni> :-)
[15:56:23] <jepler> alex_joni: this stuff I keep pasting by accident is an experimental patch for 'halcmd newinst'
[15:56:28] <jepler> why I keep pasting it I can't say
[15:56:38] <alex_joni> jepler: I read the logs
[15:56:42] <alex_joni> and your talk to jmk
[15:56:49] <alex_joni> sounds like a good thing :)
[15:56:54] <alex_joni> exciting even
[15:57:08] <jepler> yeah but he wants the very best thing, while I'm aiming firmly at "good enough"
[15:57:12] <alex_joni> jepler: I think it still can be done using the var file
[15:57:28] <alex_joni> and using the inverseKins for loading
[15:58:09] <alex_joni> err.. kinematicsForward()
[15:58:15] <SWPadnos> does it make it easier to save joint positions, and calculate the resulting cartesian location?
[15:58:24] <alex_joni> SWPadnos: lots easier
[15:58:30] <alex_joni> at least safer
[15:58:31] <SWPadnos> oh. then I'd do that ;)
[15:58:39] <alex_joni> but it involves a LOT more coding
[15:58:40] <cradek> how do g28 etc work with nontrivkins?
[15:59:04] <cradek> they save axis positions I guess
[15:59:13] <alex_joni> what's g28 again?
[15:59:24] <cradek> go to the predefined position saved in those variables
[15:59:48] <alex_joni> bet it works only once homed
[15:59:55] <SWPadnos> actually, it's "go somewhere if specified, then to the position in the vars"
[16:00:05] <SWPadnos> both are, but using separate sets of vars
[16:00:06] <cradek> oh right I forgot about that
[16:00:15] <SWPadnos> (I don't know that - I just read it)
[16:00:27] <cradek> I knew that but forgot
[16:00:47] <cradek> I use it as a shortcut for g0g53x0y0z0, which I use before exiting emc in order to get a "saved" position
[16:00:53] <SWPadnos> that's actually a cool feature - you can home after making a part, but first pop ot to e.g. a safe Z height
[16:01:32] <alex_joni> heh
[16:01:43] <alex_joni> SWPadnos: getting back to joint positions
[16:01:57] <alex_joni> it would mean canon, task and interpreted would need to learn what joints are
[16:02:24] <alex_joni> s/interpreted/interpreter/
[16:02:39] <SWPadnos> I suppose that is a problem
[16:02:54] <alex_joni> only a SMOP as cradek would say
[16:03:02] <SWPadnos> and of course, you may have kins that allow for multiple joint position sets to result in the same cartesian machine position
[16:03:23] <alex_joni> if you save joint positions it shouldn't matter
[16:03:35] <alex_joni> if you save cartesian position.. it matters
[16:04:05] <SWPadnos> right -I was just thinking about the problem with determining joint positions from a cartesian position (stored in the var file)
[16:04:23] <SWPadnos> since the interp <-> canon interface is cartesian
[16:04:33] <alex_joni> all the interfaces are cartesian
[16:04:38] <alex_joni> even motion <-> task
[16:04:45] <SWPadnos> well, motion -> HAL isn't ;)
[16:05:37] <alex_joni> don't even go there
[16:05:49] <alex_joni> :-)
[16:06:01] <SWPadnos> heh
[16:07:31] <SWPadnos> speaking of going, I think I'll pack for my trip now. I should bbl for a bit
[16:09:48] <Skunkworks> would there not be an issue with steppers - shut off at one micro step in the series - turn on at a differnt?
[16:10:23] <Skunkworks> (saving position)
[16:10:41] <alex_joni> Skunkworks: probably
[16:11:05] <alex_joni> but I can live with that
[16:11:22] <alex_joni> I'm sure you can't home better than that by eye
[16:11:23] <Skunkworks> you would have no clue where the drive was in its cycle. so you could be off by one step I suppose.
[16:11:32] <alex_joni> right
[16:11:42] <Skunkworks> right
[16:11:46] <cradek> I bet my home switch is not even good to one step
[16:12:00] <alex_joni> cradek: if it's optical it might be
[16:12:05] <alex_joni> otherwise surely not
[16:12:17] <Skunkworks> I could just see someone doing it over and over again and wonder why it was accumulating error
[16:12:21] <cradek> on the nist lathe I could home to the correct step by looking at the handwheel markings
[16:12:36] <cradek> I'd home on the switches and then maybe turn the handwheel one step by hand to the zero mark
[16:12:37] <alex_joni> Skunkworks: this won't home the machine
[16:12:53] <Skunkworks> (I ment turn the machine off and on and off and on ;)
[16:13:02] <alex_joni> Skunkworks: actually emc
[16:13:07] <alex_joni> no machine off/on
[16:13:11] <alex_joni> not machine off/on
[16:13:20] <Skunkworks> ok - then never mind :)
[16:13:22] <cradek> I would hope everyone understand that a machine can lose position when the controller is off
[16:13:35] <cradek> now just pretend that sentence made sense
[16:13:41] <alex_joni> * alex_joni pretends
[16:14:22] <Skunkworks> (I was figuring shutting the machine and emc off - coming back and turning it back on)
[16:14:41] <alex_joni> Skunkworks: bet you don't do that 100 times/day
[16:14:42] <cradek> yeah that too
[16:15:03] <cradek> seems like anytime you disable the drives, you might be off a step or more
[16:15:19] <cradek> that's not a software issue :-)
[16:15:38] <alex_joni> even when switching to ESTOP RESET
[16:15:49] <alex_joni> if you have an enable pin
[16:15:52] <cradek> right
[16:17:03] <alex_joni> argh.. why can't this be easy :/
[16:17:21] <alex_joni> canon has no way of outputting data, or calling motion stuff
[16:17:36] <alex_joni> I'm weary about adding such a thing..
[16:17:54] <Skunkworks> We have a sanko that has to be home-ed every time you do anything. pain in ass
[16:29:26] <jepler> I'd gladly give up coffee for a sanko
[16:35:49] <Skunkworks> sankyo
[16:35:52] <Skunkworks> :)
[16:36:00] <alex_joni> sanko?
[16:37:19] <Skunkworks> sanka
[16:37:28] <alex_joni> sankya?
[16:37:58] <jepler> with "sanka", it's from a song in a musical
[17:04:03] <alex_joni> bbl
[18:32:31] <jepler> http://emergent.unpy.net/files/sandbox/emc2-remember-position.txt
[18:32:46] <jepler> it doesn't use the interpreter, but a new file just for the purpose of storing the last joint positions
[18:32:55] <jepler> therefore, it should also work for nontrivial machines
[18:33:28] <cradek> slick
[18:33:36] <jepler> it's optional, only if you specify [TRAJ]POSITION_FILE
[18:33:49] <cradek> EMCMOT_MAX_AXIS is the number of ... joints?
[18:33:54] <jepler> umm
[18:33:57] <jepler> sure looks that way
[18:34:19] <cradek> so the max joint number is ... MAX_AXIS-1?
[18:34:31] <cradek> * cradek squints
[18:34:35] <jepler> I think so
[18:34:38] <jepler> what bit are you worried about?
[18:34:48] <cradek> oh nothing, and it's not your fault
[18:43:18] <jepler> alex_joni: when you get back can you take a look at that patch and tell me what you think?
[18:44:00] <cradek> it looks great to me
[18:44:08] <cradek> that fopen puts it in the config dir, right?
[18:49:41] <jepler> yes because that's the working dir
[18:52:02] <alex_joni> looks good to me too
[18:52:25] <jepler> ok .. here goes
[18:54:03] <cradek> I think the reading loop is wrong
[18:54:27] <cradek> yeah I'm sure it is
[18:55:25] <cradek> oh, no it's not, sorry - it must be in a per-axis function
[18:55:50] <alex_joni> indeed it is
[18:56:01] <alex_joni> and it only sets for that axis if found
[18:56:10] <alex_joni> although I'm a bit worried about this
[18:56:20] <alex_joni> because it can set for 2 axes, and not for the third one
[18:56:31] <alex_joni> which leaves in it a kinda bad state
[18:56:36] <jepler> you think it should only set if there's data present for all the joints?
[18:56:43] <alex_joni> jepler: definately
[18:57:01] <alex_joni> a non-triv machine with one joint somewhere else.. might be broken
[18:57:15] <alex_joni> imagine a hexapod with mechanical constraints..
[18:58:50] <alex_joni> jepler: mind if I ask what you do with motor_offset ?
[18:59:06] <alex_joni> I don't see (maybe I'm missing it) where it gets used
[18:59:32] <alex_joni> or did it already exist?
[18:59:49] <alex_joni> joint->motor_offset I mean
[19:00:15] <jepler> it already existed
[19:00:41] <jepler> there's an offset between the motor position and the joint position. It's set when you home the axis. With my patch, it may also be set at startup.
[19:01:06] <alex_joni> and shouldn't it be joints[emcmotCommand->axis]=emcmotCommand->offset ?
[19:01:28] <alex_joni> joints[emcmotCommand->axis]=emcmotCommand->motor_offset
[19:01:44] <jepler> look earlier in the file. joint is set to the right element of joints[] or NULL if the axis is not value
[19:01:57] <jepler> the next case below uses joint->whatever too
[19:03:12] <alex_joni> indeed it is
[19:03:21] <alex_joni> you're right
[19:05:38] <jepler> sigh the documentation buidls slowly
[19:05:39] <jepler> builds
[19:10:33] <alex_joni> sigh.. guess I need to undo my changes
[19:11:49] <jepler> second version: http://emergent.unpy.net/files/sandbox/emc2-remember-position2.txt
[19:12:19] <jepler> you can see that emcPositionLoad only sets any motor offsets when all values were successfully read.
[19:13:17] <jepler> tested, too
[19:13:26] <alex_joni> ok.. was just about to ask that
[19:13:36] <alex_joni> do you get 0's for the non-existing axes?
[19:13:49] <jepler> yes
[19:14:04] <alex_joni> ok, commit it :)
[19:14:19] <alex_joni> * alex_joni is thinking about a small chenge though
[19:14:32] <alex_joni> change even
[19:14:38] <jepler> here's what I get in 'position.txt' (but on 8 lines):
[19:14:39] <jepler> 1.00000000000000000 0.50000000000000000 -0.33000001311302185 0.00000000000000000 0.00000000000000000 0.00000000000000000 0.00000000000000000 0.00000000000000000
[19:14:44] <jepler> what small change is that?
[19:14:54] <alex_joni> only write the number of active joints
[19:15:01] <alex_joni> and when reading checking that number
[19:15:20] <alex_joni> it might act as a safety not to mix files from different machine types
[19:15:30] <cradek> if I add a joint/axis to my ini, will this cause emc to never work again until I remove this file?
[19:15:31] <alex_joni> say you have more than one ini in a folder
[19:15:57] <jepler> the file is rewritten at exit even if it could not be read at startup
[19:16:05] <alex_joni> right, what jepler said
[19:16:08] <cradek> ok so it'll fail once
[19:16:27] <alex_joni> again.. better fail setting 3 out of 4
[19:16:29] <jepler> alex_joni: unless it makes sense for the different inifiles to share their joint positions, make sure you specify a different [TRAJ]POSITION_FILE
[19:16:43] <alex_joni> jepler: I'm not thinking about myself
[19:16:59] <alex_joni> but we need to be prepared against hordes of brainless users :D
[19:17:01] <cradek> * cradek resists lecturing about how more than one ini in a config is a terrible idea
[19:18:12] <SWPadnos> consider a shoptask-like machine, which can be a lathe or a mill
[19:18:37] <SWPadnos> it may make sense to have some of the data shared between the two inis
[19:18:39] <alex_joni> SWPadnos: shush.. he'll lecture you about ln -s config files
[19:18:45] <cradek> when we revisit non-sequential active axes (XZC), this will be only one of many things that need attention
[19:18:46] <SWPadnos> oh, damn.
[19:18:51] <SWPadnos> back to bill-paying ;)
[19:18:59] <alex_joni> can I bill you too?
[19:19:07] <alex_joni> ;-)
[19:19:12] <SWPadnos> sure
[19:19:19] <SWPadnos> at the negotiated price ;)
[19:57:48] <alex_joni> 12$/h ?
[19:58:04] <SWPadnos> $0/day, I thought
[19:58:14] <alex_joni> that's only on sundays
[19:58:19] <SWPadnos> oh
[19:58:34] <SWPadnos> well, send a bill, I'll make sure it goes in the right file ;)
[20:31:59] <SWPadnos> ok. time for me to run.
[20:32:04] <SWPadnos> see you all on Tuesday or so