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

encoder Z auto config error #41

Open
jschoch opened this issue Jan 30, 2024 · 15 comments
Open

encoder Z auto config error #41

jschoch opened this issue Jan 30, 2024 · 15 comments
Labels
bug Something isn't working

Comments

@jschoch
Copy link

jschoch commented Jan 30, 2024

net spindle_encoder-rpm rio.spindle_encoder-rpm pyvcp.spindle_encoder-rpm

this auto generated config line in custom_postgui.hal seems to throw a pin not found error

Also the docs for vin_quadencoderz don't' seem up to date or document all the options.

my config is:

{
            "type": "vin_quadencoderz",
            "pullup": true,
            "name": "spindle_encoder",
            "function": "spindle-index",
            "scale": 600.0,
            "pins": {
                "a": "33",
                "b": "30",
                "z": "29"
            }
        }, 
@multigcs
Copy link
Owner

thanks, i removed the rpm part from the generator,
the config examples are only minimal setup's , this will be better in the next version :)

@multigcs multigcs added the bug Something isn't working label Jan 30, 2024
@jschoch
Copy link
Author

jschoch commented Jan 31, 2024

how do you get the spindle speed registered? holy cow the linuxcnc docs are confusing

@jschoch
Copy link
Author

jschoch commented Feb 1, 2024

Maybe this is a G96 issue,

here is some gcode for you to test

image

%
(TEST123)
N10 G7
N11 G90 G18
N12 G21
(WHEN USING FUSION 360 FOR PERSONAL USE, THE FEEDRATE OF)
(RAPID MOVES IS REDUCED TO MATCH THE FEEDRATE OF CUTTING)
(MOVES, WHICH CAN INCREASE MACHINING TIME. UNRESTRICTED RAPID)
(MOVES ARE AVAILABLE WITH A FUSION 360 SUBSCRIPTION.)
N13 G28 U0.
N14 G28 W0.

(PROFILE ROUGHING1)
N15 T1 M6
N17 G90 G95 G18
N18 G54
N19 G97 S582 M3
N20 G0 X50. Z5.
N21 G96 D3500 S91 M3
N22 G1 Z-2. F0.1
N23 X28.203
N24 Z-12.18
N25 G3 X30. Z-15.848 I-14.191 K-5.42
N26 G1 X32. Z-14.848
N27 Z-2.
N28 X26.203
N29 Z-10.067
N30 G3 X28.203 Z-12.18 I-13.191 K-7.534
N31 G1 X30.203 Z-11.18
N32 Z-2.
N33 X24.203
N34 Z-8.537
N35 G3 X26.203 Z-10.067 I-12.191 K-9.063
N36 G1 X28.203 Z-9.067
N37 Z-2.
N38 X22.203
N39 Z-7.328
N40 G3 X24.203 Z-8.537 I-11.191 K-10.273
N41 G1 X26.203 Z-7.537
N42 Z-2.
N43 X20.203
N44 Z-6.335
N45 G3 X22.203 Z-7.328 I-10.191 K-11.265
N46 G1 X24.203 Z-6.328
N47 Z-2.
N48 X18.203
N49 Z-5.506
N50 G3 X20.203 Z-6.335 I-9.191 K-12.095
N51 G1 X22.203 Z-5.335
N52 Z-2.
N53 X16.203
N54 Z-4.807
N55 G3 X18.203 Z-5.506 I-8.191 K-12.793
N56 G1 X20.203 Z-4.506
N57 Z-2.
N58 X14.203
N59 Z-4.22
N60 G3 X16.203 Z-4.807 I-7.191 K-13.381
N61 G1 X18.203 Z-3.807
N62 Z-2.
N63 X12.203
N64 Z-3.729
N65 G3 X14.203 Z-4.22 I-6.191 K-13.872
N66 G1 X16.203 Z-3.22
N67 Z-2.
N68 X10.203
N69 Z-3.324
N70 G3 X12.203 Z-3.729 I-5.191 K-14.276
N71 G1 X14.203 Z-2.729
N72 Z-2.
N73 X8.203
N74 Z-2.999
N75 G3 X10.203 Z-3.324 I-4.191 K-14.601
N76 G1 X12.203 Z-2.324
N77 Z-2.
N78 X6.203
N79 Z-2.749
N80 G3 X8.203 Z-2.999 I-3.191 K-14.852
N81 G1 X10.203 Z-1.999
N82 Z-2.
N83 X4.669
N84 Z-2.605
N85 G3 X6.203 Z-2.749 I-2.424 K-14.996
N86 G1 X8.203 Z-1.749
N87 Z-2.
N88 X3.135
N89 Z-2.501
N90 G3 X4.669 Z-2.605 I-1.657 K-15.1
N91 G1 X6.669 Z-1.605
N92 X31.203
N93 Z-23.154
N94 X31.
N95 X30.
N96 G3 X28.203 Z-26.821 I-15.089 K1.753
N97 G1 Z-47.615
N98 X30.
N99 X32. Z-46.615
N100 Z-26.821
N101 X29.203
N102 X28.203
N103 G3 X26.203 Z-28.935 I-14.191 K5.42
N104 G1 Z-47.615
N105 X28.203
N106 X30.203 Z-46.615
N107 Z-28.935
N108 X27.203
N109 X26.203
N110 G3 X24.862 Z-30.003 I-13.191 K7.534
N111 G2 X24.203 Z-30.49 I34.754 K-23.861
N112 G1 Z-47.615
N113 X26.203
N114 X28.203 Z-46.615
N115 Z-30.49
N116 X25.203
N117 X24.203
N118 G2 X22.203 Z-32.066 I35.083 K-23.374
N119 G1 Z-47.615
N120 X24.203
N121 X26.203 Z-46.615
N122 Z-32.066
N123 X23.203
N124 X22.203
N125 G2 X20.203 Z-33.814 I36.083 K-21.798
N126 G1 Z-47.615
N127 X22.203
N128 X24.203 Z-46.615
N129 Z-33.814
N130 X21.203
N131 X20.203
N132 G2 X18.203 Z-35.786 I37.083 K-20.05
N133 G1 Z-47.615
N134 X20.203
N135 X22.203 Z-46.615
N136 Z-35.786
N137 X19.203
N138 X18.203
N139 G2 X16.203 Z-38.063 I38.083 K-18.079
N140 G1 Z-47.615
N141 X18.203
N142 X20.203 Z-46.615
N143 Z-38.063
N144 X17.203
N145 X16.203
N146 G2 X14.203 Z-40.806 I39.083 K-15.801
N147 G1 Z-47.615
N148 X16.203
N149 X18.203 Z-46.615
N150 Z-40.806
N151 X15.203
N152 X14.203
N153 G2 X12.596 Z-43.596 I40.083 K-13.058
N154 G1 Z-47.615
N155 X14.203
N156 X16.203 Z-46.615
N157 Z-43.596
N158 X13.596
N159 X12.596
N160 G2 X10.988 Z-47.615 I40.887 K-10.268
N161 G1 X12.596
N162 X14.596 Z-46.615
N163 X50.
N164 Z5.
N165 G97 S582 M3

N166 M5
N167 G28 U0.
N168 G28 W0.
N169 M30
%

@multigcs
Copy link
Owner

multigcs commented Feb 1, 2024

sorry, my experience with lathes is very limited, so many things have not yet been implemented.
I'll try to implement it at the weekend

thanks for the test code

@jschoch
Copy link
Author

jschoch commented Feb 1, 2024

from the research i did yesterday there needs to be some notion of velocity that can then be used as feedback for G96. Do you use Discord? maybe easier to collaborate there.

@multigcs
Copy link
Owner

multigcs commented Feb 1, 2024

i have no Discord, sorry.

for G96, we 'only' need to feed the 'spindle.0.speed-in' with the encoder RPS (revolutions per second)
the problem is to calculate this value. I have it now in the rewrite repository, but i have to 'backport' it to the main branch.

@multigcs
Copy link
Owner

multigcs commented Feb 1, 2024

ok, testrun with your file looks ok, the z-axis movements are dependent on the spindle speed :) .

what are the lines for:
N13 G28 U0.
N14 G28 W0.

i have no U or W axis configured, do i need this axis ???

@jschoch
Copy link
Author

jschoch commented Feb 1, 2024

comment those out, not sure why fusion360 post put them in

@multigcs
Copy link
Owner

multigcs commented Feb 1, 2024

can you send me your json config ?

@jschoch
Copy link
Author

jschoch commented Feb 1, 2024

@jschoch
Copy link
Author

jschoch commented Feb 5, 2024

I decided to try to write a hal module to calculate the velocity, turns out I'm a terrible programmer..

#include "rtapi.h"              /* RTAPI realtime OS API */
#include "rtapi_app.h"          /* RTAPI realtime module decls */
#include "rtapi_string.h"
#include "hal.h"                /* HAL public API decls */

/* module information */
MODULE_AUTHOR("Jesse Schoch");
MODULE_DESCRIPTION("Encoder Velocity for RIO encoder with z ");
MODULE_LICENSE("GPL");

static int num_chan;
static int default_num_chan=1;
static int howmany;
RTAPI_MP_INT(num_chan, "RIO ENC number of encoder channels");

#define MAX_CHAN 8
char *names[MAX_CHAN] = {0,};
RTAPI_MP_ARRAY_STRING(names, MAX_CHAN, "names of encoder");

/***********************************************************************
*                STRUCTURES AND GLOBAL VARIABLES                       *
************************************************************************/

/* data that is atomically passed from fast function to slow one */

typedef struct {
    char count_detected;
    char index_detected;
    hal_s32_t raw_count;
    rtapi_u32 timestamp;
    rtapi_s32 index_count;
} atomic;

/* this structure contains the runtime data for a single counter
   u:rw means update() reads and writes the
   c:w  means capture() writes the field
   c:s u:rc means capture() sets (to 1), update() reads and clears
*/

typedef struct {
    hal_s32_t raw_count;                /* c:rw captured raw_count */
    hal_s32_t *raw_count_in;
    hal_s32_t *prev_raw_count;
    rtapi_u32 timestamp;                /* c:rw captured timestamp */
    hal_s32_t *count;           /* c:w captured binary count value */
    hal_float_t *min_speed;     /* c:r minimum velocity to estimate nonzero */
    hal_float_t *vel;           /* c:w scaled velocity (floating point) */
    hal_float_t *vel_rpm;   /* rps * 60 for convenience */
    hal_float_t *pos_scale;     /* c:r pin: scaling factor for pos */
    hal_s32_t *updates;
    double scale;               /* c:rw reciprocal value used for scaling */
    int counts_since_timeout;   /* c:rw used for velocity calcs */
} counter_t;

static rtapi_u32 timebase;              /* master timestamp for all counters */

/* pointer to array of counter_t structs in shmem, 1 per counter */
static counter_t *counter_array;


/* other globals */
static int comp_id;             /* component ID */

/***********************************************************************
*                  LOCAL FUNCTION DECLARATIONS                         *
************************************************************************/

static int export_encoder(counter_t * addr,char * prefix);
static void update(void *arg, long period);

/***********************************************************************
*                       INIT AND EXIT CODE                             *
************************************************************************/

int rtapi_app_main(void){

    int n, retval, i;
    counter_t *cntr;

    // fuck with stupid index and array howmany counter nightmare
    //
    //
    //
    if(num_chan && names[0]) {
        rtapi_print_msg(RTAPI_MSG_ERR,"num_chan= and names= are mutually exclusive\n");
        return -EINVAL;
    }
    if(!num_chan && !names[0]) num_chan = default_num_chan;

    if(num_chan) {
        howmany = num_chan;
    } else {
        howmany = 0;
        for (i = 0; i < MAX_CHAN; i++) {
            if ( (names[i] == NULL) || (*names[i] == 0) ){
                break;
            }
            howmany = i + 1;
        }
    }
    comp_id = hal_init("xenc_vel");
    if (comp_id < 0) {
        rtapi_print_msg(RTAPI_MSG_ERR, "ENCODER: ERROR: hal_init() failed\n");
        return -1;
    }
    /* allocate shared memory for counter data */
    counter_array = hal_malloc(howmany * sizeof(counter_t));
    if (counter_array == 0) {
        rtapi_print_msg(RTAPI_MSG_ERR,
            "ENCODER: ERROR: hal_malloc() failed\n");
        hal_exit(comp_id);
        return -1;
    }
    /* init master timestamp counter */
    timebase = 0;

    // export all the variables for each counter
    i = 0; // for names= items
    for (n = 0; n < howmany; n++) {
        // point to struct
        cntr = &(counter_array[n]);
        // export all vars
        if(num_chan) {
            char buf[HAL_NAME_LEN + 1];
            rtapi_snprintf(buf, sizeof(buf), "encoder.%d", n);
            retval = export_encoder(cntr,buf);
        } else {
            retval = export_encoder(cntr,names[i++]);
        }
        if (retval != 0) {
            rtapi_print_msg(RTAPI_MSG_ERR,
                "ENCODER: ERROR: counter %d var export failed\n", n);
            hal_exit(comp_id);
            return -1;
        }

        // init counter
        *(cntr->raw_count_in) = 0;
        *(cntr->prev_raw_count) = 0;
        *(cntr->updates) = -1;
        cntr->timestamp = 0;
        //*(cntr->vel) = 0.0;

    }




    retval = hal_export_funct("enc_vel.update-counters", update,
        counter_array, 0, 0, comp_id);
    if (retval != 0) {
        rtapi_print_msg(RTAPI_MSG_ERR,
            "ENCODER: ERROR: count funct export failed\n");
        hal_exit(comp_id);
        return -1;
    }
    rtapi_print_msg(RTAPI_MSG_INFO,
        "ENCODER: installed %d encoder counters\n", howmany);
    hal_ready(comp_id);
    return 0;
}


void rtapi_app_exit(void)
{
    hal_exit(comp_id);
}

/***********************************************************************
*            REALTIME ENCODER COUNTING AND UPDATE FUNCTIONS            *
************************************************************************/

static void update( void *arg, long period){
        int n;
        counter_t *cntr;
        cntr = arg;
        rtapi_s32 delta_counts;
        rtapi_u32 delta_time;
        double vel;


        for(n=0;n < howmany; n++){
                if(  *(cntr->prev_raw_count) != *(cntr->raw_count_in)) {
                        // encoder changed, do some updates

                        //delta_time = buf->timestamp - cntr->timestamp;
                        delta_time = timebase - cntr->timestamp;
                        //delta_counts = buf->raw_count - cntr->raw_count;
                        delta_counts = *(cntr->prev_raw_count) - *(cntr->raw_count_in);
                        cntr->timestamp = timebase + period;
                        vel = delta_counts / (delta_time * 1e-9);
                        rtapi_print_msg(RTAPI_MSG_INFO,
                                "vel %f delta_counts: %i delta_time %u\n", vel,delta_counts,delta_time);

                        *(cntr->updates)= *(cntr->updates) + 1;
                        *(cntr->prev_raw_count) = *(cntr->raw_count_in);
                        //*(cntr->vel) = vel;

                }

                // go to next encoder
                cntr++;
        }


        // update main timestamp thing
        timebase += period;

}




/***********************************************************************
*                   LOCAL FUNCTION DEFINITIONS                         *
************************************************************************/
static int export_encoder(counter_t * addr,char * prefix)
{
    int retval, msg;

    /* This function exports a lot of stuff, which results in a lot of
       logging if msg_level is at INFO or ALL. So we save the current value
       of msg_level and restore it later.  If you actually need to log this
       function's actions, change the second line below */
    msg = rtapi_get_msg_level();
    rtapi_set_msg_level(RTAPI_MSG_INFO);

    retval = hal_pin_s32_newf(HAL_OUT, &(addr->prev_raw_count), comp_id,
                    "%s.prev_raw_count",prefix);
    if(retval != 0){
            return retval;
    }
    retval = hal_pin_s32_newf(HAL_OUT, &(addr->updates), comp_id,
                    "%s.updates",prefix);
    if(retval != 0){
            return retval;
    }
    /*

    retval = hal_pin_s32_newf(HAL_OUT, &(addr->delta_time), comp_id,
                    "%s.delta_time",prefix);
    if(retval != 0){
            return retval;
    }

    retval = hal_pin_s32_newf(HAL_OUT, &(addr->delta_count), comp_id,
                    "%s.delta_count",prefix);
    if(retval != 0){
            return retval;
    }
        */


    retval = hal_pin_s32_newf(HAL_IN, &(addr->raw_count_in), comp_id,
         "%s.raw_count_in",prefix);
   if (retval != 0){
        rtapi_print("Enc Vel in probelm");
        return retval;
   }
   return 0;
}

hal config (rio.hal)

#Encoder RIO play
#

loadrt xenc_vel num_chan=1
addf enc_vel.update-counters servo-thread

net  asshole rio.spindle_encoder-s32 => encoder.0.raw_count_in

it kinda works but when i try to update the cntr->vel value it coredumps.

@multigcs
Copy link
Owner

multigcs commented Feb 5, 2024

sorry, I'm a bit busy at the moment, mostly due to uninitialized pointers or divisions by 0

@jschoch
Copy link
Author

jschoch commented Feb 7, 2024

I have it sorta working but I don't understand a few thing about how the encoder is expected to work in linuxcnc.

One question I had for you regarding the fpga component is that it seems to count in 1x mode not quadrature mode. do I need to set QUAD_TYPE, it isn't clear what that is.

also wondering how revolutions are tracked and how rollovers are dealt with.

@multigcs
Copy link
Owner

multigcs commented Feb 7, 2024

the quadType do only divide the counter by 4 to have the 'normal' resolution like in other software libs.

assign pos = $signed(count>>>QUAD_TYPE);

if you set it to 0, you have a 4 times higher resolution (each state change will count (A/B))

rollovers are not handled, it use the full 32bit (+- 2 147 483 647) range,
i think it's hard to reach this value

on a lathe with 1200RPM and an encoder resolution of 2400 steps/rev, you need 12.4 hour inside a G33 operation to reach this value :)

for the speed, you have each 12.4 hour a wrong calculation for 1/1000 second, don't know if this is an issue

@jschoch
Copy link
Author

jschoch commented Feb 7, 2024

if is set the encoder scale to 1 the raw counts are 360 per revolution with the default quadType = 0 setting. The datasheet on my encoder says it is 360 CPR, 1440 PPR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants