for QT and c ++ lovers -tutorial- (...sort off...)

More
19 Jan 2022 11:50 - 19 Jan 2022 21:01 #232427 by bkt
  1. FOR FIRST: "sort off" is a quote from a famous video show .... and almost everything here will be a quote and very little will be the fruit of my work. So thank you to everyone who participated in the process not all are correctly and rightly mentioned ....
  2. a lot of year ago "arkEye" learn me about "c" component ... a lot of that trick was used from 2014 to now
  3. next year sebastianKuminzky advice me about "position logger" file ...
  4. same year AndyPugh notice me about nml and nist ... (plus help me to solve all my low level problem and not only that ... so very thanks)
  5. Unfortunately have not time and my programming level is low .... so that for a long time EMC_STAT macro "new" related overflow problem block my idea and work on c++
  6. recently Grotius posts recently brushed up on my ambitions and I studied the code more carefully
  7. LAST BUT NOT LEAST xemc.cc is the most suitable file for learning what to do. Now it has been eliminated it seems ... however there are many copies. The mechanism is that. 

    From here to end we talk about QT5 or QT6 c/c++ .... we use QT creator ... LinuxMint 19 ... r.t.4.19 patch ... I invite everyone to bring their experience with other OS or preempt or realtime kernel versions ....

    P.S.: do not think you have persistent help with any problems in these posts. The intention is only to make a contribution to repay what has been received in the past.
    However, if I can, if I am in the right conditions, I will not avoid answering. But know that I'm not joking when I say I don't have time. Otherwise I would have written this post in 2015.

    BKT

     
Last edit: 19 Jan 2022 21:01 by bkt.
The following user(s) said Thank You: Grotius

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 12:10 - 19 Jan 2022 12:20 #232429 by bkt
Now can start:
CONFIG += link_pkgconfig
DEFINES *= QT_USE_QSTRINGBUILDER
PKGCONFIG += opencv4
INCLUDEPATH += /usr/local/include/opencv4
LIBS += $(shell pkg-config opencv --libs)
INCLUDEPATH += /usr/local/include/
INCLUDEPATH += $$PWD/lib
INCLUDEPATH += /usr/include/linuxcnc
INCLUDEPATH += /usr/include
INCLUDEPATH += /usr/lib
DEPENDPATH += $$PWD/lib

LIBS += -lX11 -pthread -lglut -lGL -lGLU
LIBS += -lmodbus
LIBS += -L/usr/lib/x86_64-linux-gnu/libv4l/libv4l2convert.so
LIBS += -L/usr/lib/x86_64-linux-gnu/libv4l
LIBS += -lsqlite3

## because use more than these libs but not Linuxcnc related ##
LIBS += -L/usr/lib
LIBS += \
  -lm \
  -llinuxcnc \
  -lposemath \
  -lnml \
  -lrs274 \
  -llinuxcncini \
  #-lpyplugin \  ## try to use pyton_plugin but not used now ##
  -llinuxcnchal \
  #-ltooldata \  ## not understand why but lib_tooldata was not present on my normal install ##
  -lstdc++ \
  #-lboost_python39 \   ## not understand why but python3.9 was not present on my normal install ##
  #-lpython3.9 \          ## not understand why but python3.9was not present on my normal install ##
  -lcrypt \
  -lpthread \
  -ldl \
  -lutil

adding these LIB on .pro file is necessary to start with Lcnc c++ GUI
Last edit: 19 Jan 2022 12:20 by bkt.

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 12:31 - 19 Jan 2022 15:58 #232430 by bkt
here you can find xemc.cc the learning file ... but also you can find the right info on hal.h and hal_priv.c (if you have install) ... or emc.h or cannon.h (control respective .c file too).

Link  xemc.cc
But maybe for some reason in future you can't find it ... so see my attach.

An other good start to learn is halui.cc file .... that as xemc.cc interact with Linuxcnc as every gui need to do ....
Attachments:
Last edit: 19 Jan 2022 15:58 by bkt.
The following user(s) said Thank You: tommylight

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 13:11 - 19 Jan 2022 15:08 #232432 by bkt
I will not bore you with the problems I had to face to understand something ... I can only say that having a code example is quite simple to make a position logger .... but it is just enough to do a test and say "you see how good what are they? " .... in reality you need to manage the memory buffer that otherwise goes into overbuffer and blocks your nice little game just made .... years ago I didn't have the knowledge and I only recently had it .....

On these post udoS user  with Help of Reinhard and Grotius  show us the power of "peek" macro .... tha works in the magic manner to solve "overbuffer" problem

void MainWindow::updnmlval()
    {
      if(!stat->valid())
      txtwrite.append ("-- 9.) ************* *stat:= INVALID \n");
      ui->tb_StartUpInfo->setText(txtwrite   +   "\n");

      if(stat->valid())
      {
       [color=#e74c3c]if(stat->peek() == EMC_STAT_TYPE)
       {
        EMC_STAT *emcStatus = static_cast<EMC_STAT*>(stat->get_address());[/color]




these is the most interesting things when you approach a c++ gui with LinuxCnc .... but ....
Last edit: 19 Jan 2022 15:08 by bkt.

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 13:21 - 19 Jan 2022 13:28 #232433 by bkt
after this, which gives a lot of satisfaction and makes you think you are some kind of programming dragon, there is the problem that the world outside your imagination sees a nothing in this ..... the rest of the world will think that it is all rather silly if it cannot interact between the program and your machine.

So you need to connect every pin of your machine at the right GREMLIN widget .... Do not be too hasty ... to date I still have no idea how to interface DRO to your gui for example .... also because it is not my intention .... the work of Grotius (skynet or hal-core) it's more than perfect for that and I see no reason to improve .... however we have other things to connect to our interface .... see you later.
Last edit: 19 Jan 2022 13:28 by bkt.

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 16:51 - 19 Jan 2022 16:56 #232449 by bkt
so need to connect some pin ..... the easy one .... "motion-digital-out-xx". Not understand and really no time to search for ... but seems there are a sort off double check, or filter for exclude at all middle-state signal, when change motion-digital-out-xx (really well done) so you need to activate command, declare pin number, establish what is 0 and what is 1 .... and use that for realize inversion of out .... a sample code:
void MainWindow::motPinOn(int idOn)
{
    EMC_MOTION_SET_DOUT dout;
    dout.now=1;
    dout.index=idOn;
    dout.start=1;
    dout.end=0;
    cmd_one->write(&dout);
    qDebug() << "Pin " <<  idOn << " on";
}

void MainWindow::motPinOff(int idOff)
{
    EMC_MOTION_SET_DOUT dout;
    dout.now=1;
    dout.index=idOff;
    dout.start=0;
    dout.end=1;
    cmd_one->write(&dout);
    qDebug() << "Pin " <<  idOff << " off";
}

void MainWindow::on_pbtn_on_pressed()
{
    motPinOn(1);
}

void MainWindow::on_pbtn_off_pressed()
{
    motPinOff(1);
}

for sure is limited connection and not the best .... but short way and work ..... for sure when motion plan work these is not right way to do, because you have not control over your MOTION-DIGITAL-OUT-XX .... so need find other way to do.... see you later
Last edit: 19 Jan 2022 16:56 by bkt.

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 17:55 #232457 by bkt
These is an interesting way to do the things, or connect hal pint to our qt c++ app .... pheraps when learning Lcnc year ago, not able and not interesting to these point so I completely loose these ArkEye learning .

A little trik for userspace c++ Gui:
// For user space HAL RTAPI only ... so not error appear when use hal.h
#ifdef RTAPI
#undef RTAPI
#endif

#ifndef ULAPI
#define ULAPI
#endif

#include "hal.h"

see ... you later
The following user(s) said Thank You: Aciera

Please Log in or Create an account to join the conversation.

More
19 Jan 2022 18:12 - 19 Jan 2022 18:14 #232461 by bkt
At that time (2015) I was looking for a method to send data from a camera to Lcnc, the solution I came up with then with the help of ArkEye was the use of a custom component with socket (see these old post) ..... then I made one with libmodbus. ... at the end in recent years I have found it much better to use MB2HAL with server in local: ip 127.0.0.1 .... however even the old one is a possible way..... see you later.
Last edit: 19 Jan 2022 18:14 by bkt.

Please Log in or Create an account to join the conversation.

More
21 Jan 2022 10:20 #232624 by bkt
Grotius component hal_widget show very well as need to do for connect QT widget C++ and hal ..... but find an old post that show more or less all what need for make these magic connection .... really post was created for learn a user about C custom component userspaces but the same code is valid for learning what is the purpose of this tutorial on cooking and dishes that can be served with C ++ and Qt .... see the code (author was ArkEye that migrate to Makinekit project as I know) ...

/*This extract from my library will give you an idea about writing to and reading pins*/

int set_common(hal_type_t type, void *d_ptr, QString& value)
{
// This function assumes that the mutex is held
int retval = 0;
double fval = 0;
long lval = 0;
unsigned long ulval = 0;

    switch (type)
        {
        case HAL_BIT:
                    if( (value.contains("TRUE") || (value.contains("1"))))
                        *(hal_bit_t *) (d_ptr) = 1;
                    else if( (value.contains("FALSE") || (value.contains("0"))))
                        *(hal_bit_t *) (d_ptr) = 0;
                    else
                        retval = -EINVAL;
                    break;
        case HAL_FLOAT:
                    fval = value.toFloat();
                           *((hal_float_t *) (d_ptr)) = fval;
                    break;
        case HAL_S32:
                    lval = value.toLong();
                        *((hal_s32_t *) (d_ptr)) = lval;
                    break;
        case HAL_U32:
                    ulval = value.toULong();
                        *((hal_u32_t *) (d_ptr)) = ulval;
                    break;
        default:
                    /* Shouldn't get here, but just in case... */
                    retval = -EINVAL;
        }
    return retval;
}


int get_common(hal_type_t type, void *d_ptr, QString& value)
{
// This function assumes that the mutex is held
int retval = 0;
int bitval = 0;
double fval = 0;
long lval = 0;
unsigned long ulval = 0;
QString str;

    switch (type)
        {
        case HAL_BIT:
                    bitval = *(hal_bit_t *) (d_ptr);
                    str.sprintf("%d", bitval);
                    break;
        case HAL_FLOAT:
                    fval = *((hal_float_t *) (d_ptr));
                    str.sprintf("%f", fval);
                    break;
        case HAL_S32:
                    lval =  *((hal_s32_t *) (d_ptr));
                    str.sprintf("%ld", lval);
                    break;
        case HAL_U32:
                    ulval = *((hal_u32_t *) (d_ptr));
                    str.sprintf("%lu", ulval);
                    break;
        default:
                    /* Shouldn't get here, but just in case... */
                    retval = -EINVAL;
        }
    
        //qDebug() <<  "str string = " << str;
    value = str;
        //qDebug() <<  "value string = " << value;   
    return 0;
}



/*The mutex code is something like*/

// get mutex before accessing shared data
    rtapi_mutex_get(&(hal_data->mutex));
...
           get or set the value
...
    rtapi_mutex_give(&(hal_data->mutex));



/*When you create any pin you have to malloc the memory required to hold the data it can carry, that is the pointer.
As I said my libraries were for interfacing with Qt, I created various typedefs*/


// These are used as the basic data units for any pins created
// via the functions in this class
typedef struct {
  hal_bit_t *pin;
} bit_data_t;

typedef struct {
  hal_s32_t *pin;
} s32_data_t;

typedef struct {
  hal_float_t *pin;
} float_data_t;



/*and held the pins created in a local arrays for ease of access*/

// Access arrays    
    bit_data_t* bit_data[ARRAY_SIZE];
    s32_data_t* s32_data[ARRAY_SIZE];
    float_data_t* float_data[ARRAY_SIZE];
    
    hal_bit_t* bit_param_data[ARRAY_SIZE];
    hal_s32_t* s32_param_data[ARRAY_SIZE];
    hal_float_t* float_param_data[ARRAY_SIZE];
    
    //     if(strcmp((char*)float_name[y], name) == 0) finds name
    
    char bit_name [ARRAY_SIZE][NAME_LEN];
    char s32_name [ARRAY_SIZE][NAME_LEN];
    char float_name [ARRAY_SIZE][NAME_LEN];

    char bit_param_name [ARRAY_SIZE][NAME_LEN];
    char s32_param_name [ARRAY_SIZE][NAME_LEN];    
    char float_param_name [ARRAY_SIZE][NAME_LEN];
    
    int bit_index;      // index to the relevant array, left at last entry so size is known
    int s32_index;
    int float_index;  

    int bit_param_index;
    int s32_param_index;
    int float_param_index;




/*and this is routine to create a float pin and eneter it into the relevant array*/


int HAL_Access::createFloatPin(QString& name, bool in)
{
int retval;

    QStrncpy(lname, name, name.length());

    if(float_index >= ARRAY_SIZE)   
        {
        rtapi_print_msg(RTAPI_MSG_ERR,"ERROR: pin %s creation not possible, local array full\n", lname);
        return -1;
        }
    else
        {
        float_data_t *data = (float_data_t*)hal_malloc(sizeof(float_data_t));

        if (data == 0)
            {
            rtapi_print_msg(RTAPI_MSG_ERR, "ERROR: hal_malloc() for pin %s creation failed\n", lname);
            cleanUp();
            }
        else
            {
            float_data[float_index] = data;
            strcpy((char*)float_name[float_index++], lname);
            }
            
        retval = hal_pin_float_newf(in ? HAL_IN : HAL_OUT, &(data->pin), comp_id, "%s.%s", prefix,  lname);
        
        if (retval < 0)
            {
            rtapi_print_msg(RTAPI_MSG_ERR,"ERROR: pin %s export failed with err=%i\n", lname, retval);
            cleanUp();
            return -1;
            }
        return 0;
        }
}



/*If you write a simple comp file that creates a do nothing component with a couple of pins, run comp filename to generate a .c file
you can then see the pure C method of creating a pin.*/


struct __comp_state {
    struct __comp_state *_next;
    hal_float_t *out;
    hal_float_t *in0;
    hal_float_t *in1;
};
struct __comp_state *__comp_inst=0;
struct __comp_state *__comp_first_inst=0, *__comp_last_inst=0;


static void _(struct __comp_state *__comp_inst, long period);
static int __comp_get_data_size(void);
#undef TRUE
#define TRUE (1)
#undef FALSE
#define FALSE (0)
#undef true
#define true (1)
#undef false
#define false (0)

static int export(char *prefix, long extra_arg) {
    char buf[HAL_NAME_LEN + 1];
    int r = 0;
    int sz = sizeof(struct __comp_state) + __comp_get_data_size();
    struct __comp_state *inst = hal_malloc(sz);
    memset(inst, 0, sz);
    r = hal_pin_float_newf(HAL_OUT, &(inst->out), comp_id,
        "%s.out", prefix);
    if(r != 0) return r;
    r = hal_pin_float_newf(HAL_IN, &(inst->in0), comp_id,
        "%s.in0", prefix);
    if(r != 0) return r;
    r = hal_pin_float_newf(HAL_IN, &(inst->in1), comp_id,
        "%s.in1", prefix);
    if(r != 0) return r;
    rtapi_snprintf(buf, sizeof(buf), "%s", prefix);
    r = hal_export_funct(buf, (void(*)(void *inst, long))_, inst, 1, 0, comp_id);
    if(r != 0) return r;
    if(__comp_last_inst) __comp_last_inst->_next = inst;
    __comp_last_inst = inst;
    if(!__comp_first_inst) __comp_first_inst = inst;
    return 0;


in attach the same ... so is more simple to download it. .... see you later ...

 
Attachments:

Please Log in or Create an account to join the conversation.

More
22 Jan 2022 14:06 - 22 Jan 2022 14:12 #232785 by bkt
So after more or less 52 hour of test and learning on old post and new one ... we can reach the goal ( yes .. I'm lazy and uses "udoS" user interfaces, however i did not use a rip-install ) ... but better is explain better the system so other with no time can reproduce same result without effort  ... I don't mean without studying a little ... because this is not a restaurant it is an opensources course to learn how to cook in QT cpp some good dishes based on LinuxCnc !! .... so for now gif with result ... about explanation ( the more curious will notice hal_priv.h in my project) ... see you later

 
Attachments:
Last edit: 22 Jan 2022 14:12 by bkt.
The following user(s) said Thank You: tommylight, Pro_El

Please Log in or Create an account to join the conversation.

Time to create page: 0.137 seconds
Powered by Kunena Forum