On 2/17/2014 12:15 PM, Charles Steinkuehler wrote:
> On 2/17/2014 11:41 AM, Len Shelton wrote:
>> On 2/16/2014 3:11 PM, Charles Steinkuehler wrote:
>>> 
>>> 2) Use trivkins and setup HAL to turn one axis into two by craftily
>>> combining the commanded motion with the homing switch states.  This is
>>> easiest if HAL is doing software stepgen (just mask the step pulses in
>>> the base thread), but I'm pretty confident I can make this work pushing
>>> the logic in front of the PRU drive step/dir component (as a bonus, this
>>> setup would also work with Mesa hm2 cards and other hardware based
>>> controllers).
>>
>> 2) I believe this is the right way to do this. If the BBB cannot do 
>> this, we will be forced to add a secondary microcontroller in the pulse 
>> stream to apply the logic that we need to do this. Seems kinda silly 
>> since the software could do it. If I only knew more about LCNC 
>> programming, it already would. This is the one thing that's preventing 
>> us from moving all of our machines to the BBB immediately.
> 
> Yeah, this is the solution I'm leaning towards.  I appreciate the
> concept of gantrykins, but given how LinuxCNC deals with non-trivial
> kins, I don't think it's the way to go unless you really have a
> non-Cartesian mechanism.
> 
> As soon as I'm done with the encoder stuff I'm working on, I'll whip up
> an N-axis HAL gantry module.  My linear-delta printer will make a good
> test-bed for a 3-Axis gantry.  In addition to avoiding the "user racks
> the gantry in joint mode" problem, the HAL component will fix problems
> with homing if HOME != HOMEOFFSET, at least for the simple gantry case.

OK, I'm not done with the encoder logic yet, but I decided to take a
break and make your gantry HAL module.  It turned out to be slightly
trickier than expected, because even at homing speed on my system and
with fairly high accelerations the axis didn't just stop nicely after
hitting the switch, even though it was being commanded to.  Since I
can't just mask the generated step signals, something more sophisticated
was required.

So I added some sticky multiplexing logic that uses one of the slave
joints for feedback (it could be any of them), but hops around to track
active joints when homing.  Basically the module generates multiple
commanded positions using an offset for each joint.  The offset is fixed
while all home switches are in the same state (either all closed or all
open).  If *SOME* of the home switches are closed and movement is
towards the home switches (direction matches HOME_SEARCH_VEL), than the
joints with closed home switches are "disabled" by changing their offset
value rather than their commanded position, until all home switches are
closed, at which point the joints are run in lock-step again.

Otherwise, it's basically the same concept as the software stepgen "HAL
step masking code" provided to me by Les Shelton, which he says came
from one of the EMC lists some time ago.

For best results, make sure that HOME_SEARCH_VEL and HOME_LATCH_VEL are
the same sign (move in the same direction), since there is no special
behavior when moving the joints off of home.  I also recommend running
as slow as practical for both velocities.  The code is introducing
discontinuities in velocity (instantly changing from commanding the home
search velocity to commanding a full stop), so you wouldn't want to run
very fast on something with lots of mass.  It works pretty well on my
linear-delta Kossel, however.

Oh...and just for grins, you can have up to 7 slave joints, and I have
tested with three.  If it doesn't work for your dual-motor gantry, just
get another motor!  :)

...and I have only tested on a BeagleBone with PRU driven step/dir, but
the comp should work to drive any other "off-cpu" based control,
including Mesa hm2 step/dir and servo setups.  The main drawback is only
one joint is used to generate feedback into motion, so there's no alarm
raised if one side of the gantry gets stuck but the other is still
moving.  Adding that is left as an exercise for the reader!  :)

Hopefully, the man page makes usage obvious, if not, let me know.  The
read thread should run after capturing the current position from your
stepgen/encoders, and before motion.  The write thread should run after
motion, and before your motor controller update function.

-- 
Charles Steinkuehler
char...@steinkuehler.net
/******************************************************************************
 *
 * Copyright (C) 2014 Charles Steinkuehler (charles AT steinkuehler DOT net)
 *
 *
 * This module allows multiple drive motors (joints) to be connected to a
 * single motion axis.  This is useful for gantry style machines if you don't
 * want to use gantrykins
 *
 ******************************************************************************
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * THE AUTHORS OF THIS PROGRAM ACCEPT ABSOLUTELY NO LIABILITY FOR
 * ANY HARM OR LOSS RESULTING FROM ITS USE.  IT IS _EXTREMELY_ UNWISE
 * TO RELY ON SOFTWARE ALONE FOR SAFETY.  Any machinery capable of
 * harming persons must have provisions for completely removing power
 * from all motors, etc, before persons enter any danger area.  All
 * machinery must be designed to comply with local and national safety
 * codes, and the authors of this software can not, and do not, take
 * any responsibility for such compliance.
 *
 * This code was written as part of the LinuxCNC project.  For more
 * information, go to www.linuxcnc.org.
 *
 ******************************************************************************/

component gantry "LinuxCNC HAL component for driving multiple joints from a 
single axis";
pin out float joint.##.pos-cmd [7 : personality] "Per-joint commanded position";
pin in  float joint.##.pos-fb  [7 : personality] "Per-joint position feedback";
pin in  bit   joint.##.home    [7 : personality] "Per-joint home switch";
pin out float joint.##.offset  [7 : personality] "(debugging) Per-joint offset 
value, updated when homing";
pin in  float position-cmd "Commanded position from motion";
pin out float position-fb "Position feedback to motion";
pin out bit   home "Combined home signal, true if all joint home inputs are 
true";
pin out bit   limit "Combined limit signal, true if any joint home input is 
true";
pin in  float search-vel "HOME_SEARCH_VEL from ini file";
function read  fp "Update position-fb and home/limit outputs based on joint 
values";
function write fp "Update joint pos-cmd outputs based on position-cmd in";
description """
Drives multiple physical motors (joints) from a single axis input
.LP
The `personality' value is the number of joints to control.  Two is typical, but
up to seven is supported (a three joint setup has been tested with hardware).
.LP
All controlled joints track the commanded position (with a per-joint offset)
unless in the process of homing.  Homing is when the commanded position is
moving towards the homing switches (as determined by the sign of search-vel)
and the joint home switches are not all in the same state.  When the system is
homing and a joint home switch activates, the command value sent to that joint
is "frozen" and the joint offset value is updated instead.  Once all home
switches are active, there are no more adjustments made to the offset values
and all joints run in lock-step once more.
.LP
For best results, set HOME_SEARCH_VEL and HOME_LATCH_VEL to the same direction
and as slow as practical.  When a joint home switch trips, the commanded
velocity will drop immediately from HOME_SEARCH_VEL to zero, with no limit on
accleration.
""";
license "GPL";
variable float offset[7] = 0.0;
variable float prev_cmd = 0.0;
variable int   fb_joint = 0;
;;
FUNCTION(read) {
    int i=1;

    // First (or only) joint
    home=joint_home(0);
    limit=joint_home(0);

    // All other joints, if configured
    while (i < personality) {
        home  &= joint_home(i);
        limit |= joint_home(i);
        i++;
    }

    // Joint used for feedback is 'sticky', but we have to switch to
    // track active joints or motion gets upset with the sudden
    // stop.  If all joints are not homed, but the current joint used
    // for feedback is, find a joint that's still active
    if ((joint_home(fb_joint) == 1) && (home == 0)) {
        for (i=0; i < personality; i++) {
            if (joint_home(i) == 0) {
                position_fb = joint_pos_fb(i) + offset[i];
                fb_joint = i;
                break;
            }
        }
    } else {
        position_fb = joint_pos_fb(fb_joint) + offset[fb_joint];
    }
}

FUNCTION(write) {
    int i;
    float delta;

    // Determine if we're moving in the same direction as home search

    // First calculate the direction we're moving now
    delta = position_cmd - prev_cmd;

    // Stash current commanded position for next time
    prev_cmd = position_cmd;

    // Then multiply our delta value by the search velocity
    // If the signs match and neither is zero, the result will be positive
    // indicate we are moving towards home.  Otherwise, the result will be
    // zero or negative.
    //
    // If we're moving towards home and all home switches are not closed
    if ( ((delta * search_vel) > 0) && (home==0) ) {
        // Check each joint to see if it's home switch is active
        for (i=0; i < personality; i++) {
            // If home switch is active, update offset, not pos_cmd
            // so the other joints can catch up
            if (joint_home(i)==1) {
                offset[i] += delta;
            }
        }
    }

    // Update each joint's commanded position
    for (i=0; i < personality; i++) {
        joint_pos_cmd(i) = position_cmd - offset[i];
        joint_offset(i)  = offset[i];
    }
}

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk
_______________________________________________
Emc-users mailing list
Emc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/emc-users

Reply via email to