Troubles with multiple functions in a component
11 Nov 2013 23:46 #40741
by ArcEye
Replied by ArcEye on topic Troubles with multiple functions in a component
No problem
Sometimes the more you look at something and the more familiar you are with it, the less you see.
It is peculiar that it just warns that the test value is outside the range of the variable, expected it would error, the same as it would if you tried to assign those values.
regards
I plainly missed the bit in the switch, I saw it over and over, it just didnt click and didnt throw the error.
Sometimes the more you look at something and the more familiar you are with it, the less you see.
It is peculiar that it just warns that the test value is outside the range of the variable, expected it would error, the same as it would if you tried to assign those values.
regards
Please Log in or Create an account to join the conversation.
12 Nov 2013 05:22 #40758
by andypugh
It's normal to use an int (or a char) as a boolean in C. (wasteful, but normal).
I think some parts of LinuxCNC (including comp) might now be using the boolean_t that (I think) is defined in the kernel headers.
It used to be possible to have values in HAL "bit" pins that were not 0 or 1. And that could cause some very odd behaviour. (It might still be possible)
Replied by andypugh on topic Troubles with multiple functions in a component
It is peculiar that it just warns that the test value is outside the range of the variable, expected it would error, the same as it would if you tried to assign those values.
It's normal to use an int (or a char) as a boolean in C. (wasteful, but normal).
I think some parts of LinuxCNC (including comp) might now be using the boolean_t that (I think) is defined in the kernel headers.
It used to be possible to have values in HAL "bit" pins that were not 0 or 1. And that could cause some very odd behaviour. (It might still be possible)
Please Log in or Create an account to join the conversation.
07 Jan 2014 03:56 #42398
by JR1050
Replied by JR1050 on topic Troubles with multiple functions in a component
Hello,
Im.at the point where im.actually testing the comps ive written with the multiple functions, and, im getting realtime errors or the main function simply refuses to call a sub function. Is this par for the course with the realtime system, or are there some things im missing? Thanks
JR
Im.at the point where im.actually testing the comps ive written with the multiple functions, and, im getting realtime errors or the main function simply refuses to call a sub function. Is this par for the course with the realtime system, or are there some things im missing? Thanks
JR
Please Log in or Create an account to join the conversation.
07 Jan 2014 04:00 #42399
by andypugh
You might get realtime errors if your comp does any waiting. Does every function run to completion as fast as possible every time?
Kernel space is tricksy, some things you might be used to are not available.
Replied by andypugh on topic Troubles with multiple functions in a component
Im.at the point where im.actually testing the comps ive written with the multiple functions, and, im getting realtime errors or the main function simply refuses to call a sub function.
You might get realtime errors if your comp does any waiting. Does every function run to completion as fast as possible every time?
Kernel space is tricksy, some things you might be used to are not available.
Please Log in or Create an account to join the conversation.
07 Jan 2014 04:03 #42400
by JR1050
Replied by JR1050 on topic Troubles with multiple functions in a component
Some sections of.the.code have delays in them while waiting for a switch to be made or a flag to change.
Please Log in or Create an account to join the conversation.
07 Jan 2014 04:13 #42401
by andypugh
If it's a realtime module then you can't do that.
You need to code that sort of thing as a state machine.
So, the code always exits immediately, but knows what it was doing last time when it re-enters
Replied by andypugh on topic Troubles with multiple functions in a component
Some sections of.the.code have delays in them while waiting for a switch to be made or a flag to change.
If it's a realtime module then you can't do that.
You need to code that sort of thing as a state machine.
static int the_state = 0
switch (the_state) {
case 0: // Init code
...
the_state = 1;
break:
case 1: // waiting
if (flag == true) state = 2;
break;
case 2:
// Do something
the_state=1; // go back to waiting
}
So, the code always exits immediately, but knows what it was doing last time when it re-enters
Please Log in or Create an account to join the conversation.
07 Jan 2014 04:21 #42402
by JR1050
Replied by JR1050 on topic Troubles with multiple functions in a component
It is a state machine, im using the timedelay component as a timer, as ive had luck with it before. To immediately solve the problem, i.rewrote the main function with out the sub functions as seperate sets of case statements, so instead of jumping to orient_spindle(); , it jumps to case 200 ect. It seems to work, but i would have preferred to have pulled it off with single functions, it was less cumbersome. I can post the original comp, it will be an hour or so though, maybe you might see something, it would be hugely appreciated.....
Please Log in or Create an account to join the conversation.
07 Jan 2014 06:20 #42409
by JR1050
Replied by JR1050 on topic Troubles with multiple functions in a component
original component with multiiple functions.
Please Log in or Create an account to join the conversation.
07 Jan 2014 07:18 #42414
by andypugh
Replied by andypugh on topic Troubles with multiple functions in a component
It's a bit late to look at that in detail now, but some comments about things that are probably not the issue.
Your indenting is strange. If your editor allows it, try auto-indenting and see if it still looks right.
In fact: pastebin.com/LsZvC1rZ
Is your code auto-indented, and it looks like all your "else" clauses are incorrectly bracketed.
The syntax is
if (condition) {
// firs set of code
}
else
{
// second set of code
}
Though
} else {
is not unusual. In any case the "else" or "elseif" needs a new { and a } at the end.
Your indenting is strange. If your editor allows it, try auto-indenting and see if it still looks right.
In fact: pastebin.com/LsZvC1rZ
Is your code auto-indented, and it looks like all your "else" clauses are incorrectly bracketed.
The syntax is
if (condition) {
// firs set of code
}
else
{
// second set of code
}
Though
} else {
is not unusual. In any case the "else" or "elseif" needs a new { and a } at the end.
Please Log in or Create an account to join the conversation.
07 Jan 2014 17:55 - 07 Jan 2014 17:58 #42429
by ArcEye
Replied by ArcEye on topic Troubles with multiple functions in a component
Hi
Several observations
The syntax question Andy raised makes things hard to follow if nothing else
could be written
and it becomes a lot easier to track stray brackets, not least because when there only one line after a conditional test you don't need them.
I think the problem is that this is not a state machine
It is superficially similar, but when you look closer, each state does not do something and return, setting its state for the next poll.
There are nested calls: FUNCTION() calls run_the_spindle(), which in turn calls free_the_spindle()
I don't know what happens to the stack between polls on a realtime component, but I think you can be fairly certain it is destroyed
Another thing I commented on earlier is still present
Because there are no break; statements after each case: ALL the cases down to and including case 8: will be executed every time a number from 0 - 7 is passed
This potentially includes 4 function calls.
The only reason for having functions is to save repeating code.
Each function could be a state number, in post 40637 I demonstrated how you can set a return state number, then use the same state (function) multiple times from different levels and control what return state was set when its condition
was satisfied.
The linear nature of the 'state machine' type coding is peculiar and not aesthetically pleasing if you are used to classes and neatly packed functions doing the work behind the scenes.
But it is the only thing that works reliably, IN -> do something -> set the next level -> OUT
regards
Several observations
The syntax question Andy raised makes things hard to follow if nothing else
switch (spl_cond){
case 40:
if(((spindle_rpm_cmd)<=800&&(in_low_gear)==1)&&((mot_spl_on)==1&&(low_gear_m141)==1))
{
spl_cond = 43;
}
else
if(((spindle_rpm_cmd)>100&&(in_low_gear)==1)&&((mot_spl_on)==1&&(hi_gear_m142)==1))
{
spl_cond = 41;
}
else
if(((spindle_rpm_cmd)>100&&(in_hi_gear)==1)&&((mot_spl_on)==1&&(hi_gear_m142)==1))
{
spl_cond = 43;
}
else
if(((spindle_rpm_cmd)<=800&&(in_low_gear)==0)&&((mot_spl_on)==1&&(low_gear_m141)==1))
{
spl_cond = 41;
}
break;
switch (spl_cond){
case 40:
if(((spindle_rpm_cmd)<=800&&(in_low_gear)==1)&&((mot_spl_on)==1&&(low_gear_m141)==1))
spl_cond = 43;
else if(((spindle_rpm_cmd)>100&&(in_low_gear)==1)&&((mot_spl_on)==1&&(hi_gear_m142)==1))
spl_cond = 41;
else if(((spindle_rpm_cmd)>100&&(in_hi_gear)==1)&&((mot_spl_on)==1&&(hi_gear_m142)==1))
spl_cond = 43;
else if(((spindle_rpm_cmd)<=800&&(in_low_gear)==0)&&((mot_spl_on)==1&&(low_gear_m141)==1))
spl_cond = 41;
break;
and it becomes a lot easier to track stray brackets, not least because when there only one line after a conditional test you don't need them.
I think the problem is that this is not a state machine
It is superficially similar, but when you look closer, each state does not do something and return, setting its state for the next poll.
There are nested calls: FUNCTION() calls run_the_spindle(), which in turn calls free_the_spindle()
I don't know what happens to the stack between polls on a realtime component, but I think you can be fairly certain it is destroyed
Another thing I commented on earlier is still present
FUNCTION(_)
{
switch (orient_cond){
case 0:
if((orient_m119)==1&&(ls1_plunger_in)==1)
{
orient_m119=0;
orient_cond = 59; //spindle is oriented
}
case 1:
if(((orient_m119)==1||(tc_orient)==1)&&(ls1_plunger_in)==0)
{
orient_feed_hold = 1; // spindle needs orient
tc_orient_comp=0;
spl_run=0;
orient_the_spindle();
}
case 2:
if((orient_m118)==1&&(ls1_plunger_in)==1) // shift to spindle free
{
orient_feed_hold = 1;
free_the_spindle();
}
case 3:
if((orient_m118)==1&&(ls1_plunger_in)==0)
{
orient_m118=0;
orient_cond = 61; // spindle is free
}
case 4:
if((low_gear_m141)==1&&((ls3_low_gear)==1&&(ls2_hi_gear)==0))
{
low_gear_m141=0;
orient_cond = 61; // spindle in low gear ,no shifting
}
case 5:
if((low_gear_m141)==1&&((ls3_low_gear)==0&&(ls2_hi_gear)==1))
{
orient_feed_hold = 1;
spl_run=0; // spindle in not low gear needs shift
shift_the_transmission();
}
case 6:
if((hi_gear_m142)==1&&((ls2_hi_gear)==1&&(ls3_low_gear)==0))
{
hi_gear_m142=0;
orient_cond = 61; // spindle in hi gear no shift
}
case 7:
if(((hi_gear_m142)==1&&(ls2_hi_gear)==0)&&(ls3_low_gear)==1)
{
orient_feed_hold = 1; // spindle not in hi gear need shift
spl_run=0;
shift_the_transmission();
}
case 8:
if(((ls3_low_gear)==1&&(ls2_hi_gear)==1)||((ls3_low_gear)==0&&(ls2_hi_gear)==0))
{
orient_cond = 62; // transmission shift malfunction
orient_feed_hold = 1;
}
break;
Because there are no break; statements after each case: ALL the cases down to and including case 8: will be executed every time a number from 0 - 7 is passed
This potentially includes 4 function calls.
The only reason for having functions is to save repeating code.
Each function could be a state number, in post 40637 I demonstrated how you can set a return state number, then use the same state (function) multiple times from different levels and control what return state was set when its condition
was satisfied.
The linear nature of the 'state machine' type coding is peculiar and not aesthetically pleasing if you are used to classes and neatly packed functions doing the work behind the scenes.
But it is the only thing that works reliably, IN -> do something -> set the next level -> OUT
regards
Last edit: 07 Jan 2014 17:58 by ArcEye.
Please Log in or Create an account to join the conversation.
Time to create page: 0.177 seconds