Toolchanger HAL Component project
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
03 Jan 2023 18:14 - 08 Jan 2023 18:33 #260861
by smc.collins
Toolchanger HAL Component project was created by smc.collins
I am designing a new hal component dedicated specifically to control the carousel or belt style tool changers. My first draft is below, it will have significant modifications made to it shortly.
Problems this is attempting to solve;
1. configuring toolchangers with current hal components, is a big pain in the ass
2. the configuration process is difficult and buggy, multiple places for failures and errors
3. the current solutions available all require a lot of hoop jumping, working in multiple languages and dealing with lots of hal pins and files
Goals and Solutions:
1. design a flexible block execution, stair case logic motion control routine
2. include popular most popular position decoding needs
3. include jog function with forward and reverse
4. include homing feature
5. make design exestensible
Issues:
1. the real time API is difficult to work with
2. I have to focus my efforts on making my machine work, but I can post my work here for others to contribute of make derivative work
3. community engagement is very low in hard projects for the most part, and this is one of the biggest obstacles to refits
Aspirations:
having a generic flexible toolchanger component for carousel and belt tool changers will improve the acess to EMC2 in general. This will likely reduce people bailing out and also help reduce the support work load on the community forum and free up man power for solving other problems. Like redesigning the RTapi in a more sane multithreaded way that uses a watchdog execution system and allows for worker threads. So that the code complexity can be reduced by using while loops etc or brining halcompile to the world or rust or c++ or a million other things that could be getting done that aren't because many of the people who can do them are burnt out or tied up answering the same questions on the forums etc.
Also reduce new user frustration greatly. This is not going to be a easy project, and I expect at least 40 days of really hard mid night oil burning to get a basic component program working. But I will start a github page and post a link tomorrow when I have a few hours to setup git.
What can you do, well, you can post up pictures and document how your toolchanger works mechanically and electrically. this is very important knowledge, the more info at the begging of this process, the easier it will be to create a more universal toolchanger component. It may end up that derivatives of this component will need to be made, but trying to cover 80% of machines first go is the broad goal but I will settle for my machine working and as many as I can make work in the meantime.
Have a great weekend, and peace out
Problems this is attempting to solve;
1. configuring toolchangers with current hal components, is a big pain in the ass
2. the configuration process is difficult and buggy, multiple places for failures and errors
3. the current solutions available all require a lot of hoop jumping, working in multiple languages and dealing with lots of hal pins and files
Goals and Solutions:
1. design a flexible block execution, stair case logic motion control routine
2. include popular most popular position decoding needs
3. include jog function with forward and reverse
4. include homing feature
5. make design exestensible
Issues:
1. the real time API is difficult to work with
2. I have to focus my efforts on making my machine work, but I can post my work here for others to contribute of make derivative work
3. community engagement is very low in hard projects for the most part, and this is one of the biggest obstacles to refits
Aspirations:
having a generic flexible toolchanger component for carousel and belt tool changers will improve the acess to EMC2 in general. This will likely reduce people bailing out and also help reduce the support work load on the community forum and free up man power for solving other problems. Like redesigning the RTapi in a more sane multithreaded way that uses a watchdog execution system and allows for worker threads. So that the code complexity can be reduced by using while loops etc or brining halcompile to the world or rust or c++ or a million other things that could be getting done that aren't because many of the people who can do them are burnt out or tied up answering the same questions on the forums etc.
Also reduce new user frustration greatly. This is not going to be a easy project, and I expect at least 40 days of really hard mid night oil burning to get a basic component program working. But I will start a github page and post a link tomorrow when I have a few hours to setup git.
What can you do, well, you can post up pictures and document how your toolchanger works mechanically and electrically. this is very important knowledge, the more info at the begging of this process, the easier it will be to create a more universal toolchanger component. It may end up that derivatives of this component will need to be made, but trying to cover 80% of machines first go is the broad goal but I will settle for my machine working and as many as I can make work in the meantime.
Have a great weekend, and peace out
Last edit: 08 Jan 2023 18:33 by smc.collins.
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
04 Jan 2023 22:38 - 08 Jan 2023 18:49 #260972
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
could someone update the thread topic please !
Last edit: 08 Jan 2023 18:49 by smc.collins.
The following user(s) said Thank You: billykid
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
08 Jan 2023 21:09 #261305
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
I hope a moderator renames this thread. if anyone is wondering I HATE underscores, they are awkward to type and I find them obnoxious to deal with later in the code particularly in the hal file pin naming, Camel Case Is More Natural To Type and you follow each instance with a Number it is easier to read and type. I will be using the Haiku Operating system coding guidelines for the most part, I find them functional and easy to read, but deviate where I feel it necassary or convenient for me.
This VariableIsEasyToName1
Step 1. design a block of reusable code, that does 4 basic things
1. read a input, compares values and commands an output,
2. can error check itself in multiple ways
3. can be accurately sequenced
4. is inexpensive to execute we have time deadlines to meet.
here is that block
1. need a timer to control the pac of the executions for some outputs
param rw float FunctionTimer0 = 0.0 " variable for timer control";
pin in float FunctionTimer0Value = 1.00 in seconds;
2. we need a watchdog to ensure the execution doesn't take to long
param rw float WatchDogTimer0 = 0.0 " variable for timer control";
3. we need a execution system to control code flow. as we enter the next block in Count2, we will set the True to False and clear the execution block from falling through as is SO problematic with execution loop.
pin out bit Count1 = false;
then we end up with this code block here with the above control variables in the hal component, this is the turret unlock routine out of my Cincinnati Lathe turret component. The plan is to refactor this into a generic block that cane be configured in the hal file. The question I have is, what are the most common types of tool changer configurations ? how many steps are there in each direction to and from the storage magazine to the spindle and back ? I am thinking I might just set this up with 10 blocks in each direction ?? I think that should cover it and then make the variables for the block numbers accessible in the hal file.
If anyone has a better alternative approach to this, lmk, I am open to idea and the code is kinda in a very amorphous state.
There is a lot happening in this block of code, execution control flags, error flags, diagnostic timeouts and messages etc. This prototype will serve as the basis for constructing the Toolchanger.comp file and program. unless someone has a better idea. The parts of other components like carousel etc could be integrated into this to reduce more hal wiring, which IMHO is a good idea. Better to debug in one place then 100
if (count1 == true){ // unlock and count1 start this timer
timer0 += fperiod; // timer is incremented by fperoid
count2_5 = true; // start timer for turret watchdog
}
if (timer0 > unlockpause && toolchanger == true){ // 1 second unlock pause
count2 = true; // move flow control forward
count1 = false; // flow control rest at start of routine
timer0 = 0; // clear timer to clean up
}
// turret unlock time watchdog system make sure turret unlocks in reasonable amount of time
if (count2_5 == true && unlock == true ){ // unlock and count2 start this timer
timer1 += fperiod; // timer is incremented by fperoid
}
else{
if (timer1 > unlocktimeout && unlock == true){ // if timer1 is greater then unlocktimeout setting and toolchange is true
count2_5 = true; // flow control rest at start of routine
}
}
if (timer1 < unlocktimeout && unlock == true){
count3 = true;
}
if (count2_5 == true && timer1 > unlocktimeout) { // just changing the timer name, becuase memory leaks
unlock = false; // disable motor
toolchanger = false; // top toolchange code flow
count100 = true; // set this error flag
estop = true; // disable machine
count2_5 = false; // cancel timer
if (set_warn_flag12 == false){ // block repetitive error messages they are annoying and flood the system
rtapi_print_msg(RTAPI_MSG_ERR, "Fault 010 TURRET TOOK TO LONG TO UNLOCK EXCEEDED ESTOP ON TOOLCHANGER DISABLED");
set_warn_flag12 = true; // set flag to block prinint excesive error messages
counterT = 105; // diagnostic counter if the program hang use this in halscope to capture the value when it does, at least you got a shot
} // diagnosing the problem
}
This VariableIsEasyToName1
Step 1. design a block of reusable code, that does 4 basic things
1. read a input, compares values and commands an output,
2. can error check itself in multiple ways
3. can be accurately sequenced
4. is inexpensive to execute we have time deadlines to meet.
here is that block
1. need a timer to control the pac of the executions for some outputs
param rw float FunctionTimer0 = 0.0 " variable for timer control";
pin in float FunctionTimer0Value = 1.00 in seconds;
2. we need a watchdog to ensure the execution doesn't take to long
param rw float WatchDogTimer0 = 0.0 " variable for timer control";
3. we need a execution system to control code flow. as we enter the next block in Count2, we will set the True to False and clear the execution block from falling through as is SO problematic with execution loop.
pin out bit Count1 = false;
then we end up with this code block here with the above control variables in the hal component, this is the turret unlock routine out of my Cincinnati Lathe turret component. The plan is to refactor this into a generic block that cane be configured in the hal file. The question I have is, what are the most common types of tool changer configurations ? how many steps are there in each direction to and from the storage magazine to the spindle and back ? I am thinking I might just set this up with 10 blocks in each direction ?? I think that should cover it and then make the variables for the block numbers accessible in the hal file.
If anyone has a better alternative approach to this, lmk, I am open to idea and the code is kinda in a very amorphous state.
There is a lot happening in this block of code, execution control flags, error flags, diagnostic timeouts and messages etc. This prototype will serve as the basis for constructing the Toolchanger.comp file and program. unless someone has a better idea. The parts of other components like carousel etc could be integrated into this to reduce more hal wiring, which IMHO is a good idea. Better to debug in one place then 100
if (count1 == true){ // unlock and count1 start this timer
timer0 += fperiod; // timer is incremented by fperoid
count2_5 = true; // start timer for turret watchdog
}
if (timer0 > unlockpause && toolchanger == true){ // 1 second unlock pause
count2 = true; // move flow control forward
count1 = false; // flow control rest at start of routine
timer0 = 0; // clear timer to clean up
}
// turret unlock time watchdog system make sure turret unlocks in reasonable amount of time
if (count2_5 == true && unlock == true ){ // unlock and count2 start this timer
timer1 += fperiod; // timer is incremented by fperoid
}
else{
if (timer1 > unlocktimeout && unlock == true){ // if timer1 is greater then unlocktimeout setting and toolchange is true
count2_5 = true; // flow control rest at start of routine
}
}
if (timer1 < unlocktimeout && unlock == true){
count3 = true;
}
if (count2_5 == true && timer1 > unlocktimeout) { // just changing the timer name, becuase memory leaks
unlock = false; // disable motor
toolchanger = false; // top toolchange code flow
count100 = true; // set this error flag
estop = true; // disable machine
count2_5 = false; // cancel timer
if (set_warn_flag12 == false){ // block repetitive error messages they are annoying and flood the system
rtapi_print_msg(RTAPI_MSG_ERR, "Fault 010 TURRET TOOK TO LONG TO UNLOCK EXCEEDED ESTOP ON TOOLCHANGER DISABLED");
set_warn_flag12 = true; // set flag to block prinint excesive error messages
counterT = 105; // diagnostic counter if the program hang use this in halscope to capture the value when it does, at least you got a shot
} // diagnosing the problem
}
Please Log in or Create an account to join the conversation.
- tommylight
- Online
- Moderator
Less
More
- Posts: 19196
- Thank you received: 6434
09 Jan 2023 01:53 #261321
by tommylight
Dedicated Hurco carousel component BMC SLV 80-90s vintage maybe others
?
Replied by tommylight on topic Toolchanger HAL Component project
Gladly, to what? This:I hope a moderator renames this thread.
Dedicated Hurco carousel component BMC SLV 80-90s vintage maybe others
?
The following user(s) said Thank You: smc.collins
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
09 Jan 2023 20:32 #261379
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
Toolchanger HAL Component project, to more accurately reflect what the goal here is
Please Log in or Create an account to join the conversation.
- tommylight
- Online
- Moderator
Less
More
- Posts: 19196
- Thank you received: 6434
10 Jan 2023 00:04 #261395
by tommylight
Replied by tommylight on topic Toolchanger HAL Component project
Done,
Thank you.
Thank you.
The following user(s) said Thank You: smc.collins
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
10 Jan 2023 02:06 - 10 Jan 2023 02:10 #261405
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
So one of the problems, with hard switch logic that iterates every single loop, is switch input noise. working within the constraints of halcompile , the linuxcnc rtapi behavior I have observed and the compiler and the code that it generates, I devised this after some trial and error for input filtering.
I plan to implement all the variables as params and io but the current variable naming is essentially there for discussion.
If anyone see's any obvious ways to improve this I am open to the idea. As you can see the camel case naming makes spotting and reading variable names much easier !
bool SwitchUF = false; // unfiltered input
bool SwitchFT = false; // filtered output
bool TimerFlag = false; // to control buffer counter
int float FilterBuffer = 0; // default state of buffer
int float TimerBuffer = 0; // timer
if ( SwitchUF != SwitchFT ){
Buffer += feriod * 100;
TimerFlag = true;
}
If (TimerFlag = true){
Timer1 += fperiod *100;
}
If (SwitchUF == true && (buffer / 10 >= 1.2) && (buffer <= timer1)){
SwitchFT = True;
Timer1 = 0;
Buffer = 0;
TimerFlag = false;
} else {
if (SwitchUF == true || false && (Buffer / 10) <= 0.7 && (Buffer < Timer1)) {
SwitchFT = false;
Timer1 = 0;
Buffer = 0;
TimerFlag = false;
}
}
I plan to implement all the variables as params and io but the current variable naming is essentially there for discussion.
If anyone see's any obvious ways to improve this I am open to the idea. As you can see the camel case naming makes spotting and reading variable names much easier !
bool SwitchUF = false; // unfiltered input
bool SwitchFT = false; // filtered output
bool TimerFlag = false; // to control buffer counter
int float FilterBuffer = 0; // default state of buffer
int float TimerBuffer = 0; // timer
if ( SwitchUF != SwitchFT ){
Buffer += feriod * 100;
TimerFlag = true;
}
If (TimerFlag = true){
Timer1 += fperiod *100;
}
If (SwitchUF == true && (buffer / 10 >= 1.2) && (buffer <= timer1)){
SwitchFT = True;
Timer1 = 0;
Buffer = 0;
TimerFlag = false;
} else {
if (SwitchUF == true || false && (Buffer / 10) <= 0.7 && (Buffer < Timer1)) {
SwitchFT = false;
Timer1 = 0;
Buffer = 0;
TimerFlag = false;
}
}
Last edit: 10 Jan 2023 02:10 by smc.collins.
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
10 Jan 2023 22:17 - 12 Jan 2023 17:28 #261502
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
I wrote a new filter algorythm, it is much simpler than my previous attempts and it acts as a debounce and rolling average filter. will post tommorow once I do a bit more debugging on it.
Got a little bit of coding done tonight. Long way to go still but I already flushed out a good bit of the needed code in the other file above. I will start merging these together soon.
I propose, Block, it can be copied and pasted relatively easily, uses a very flat construction idea and includes a error state and execution watch timer. More to come. It will be a part of the toolchanger, but it does a bunch of things. Creates the first way to adress logic steps, integrates 2 timers, and turns on a output based on inputs and conditional variables etc.
Got a little bit of coding done tonight. Long way to go still but I already flushed out a good bit of the needed code in the other file above. I will start merging these together soon.
I propose, Block, it can be copied and pasted relatively easily, uses a very flat construction idea and includes a error state and execution watch timer. More to come. It will be a part of the toolchanger, but it does a bunch of things. Creates the first way to adress logic steps, integrates 2 timers, and turns on a output based on inputs and conditional variables etc.
Last edit: 12 Jan 2023 17:28 by smc.collins.
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
11 Jan 2023 18:30 - 12 Jan 2023 17:28 #261605
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
filtering pocket values, versus de-bouncing the switches, both have trade offs, if there is a machine with a lot of input switches, pocket filtering is probably a better solution. This little snippet is working well in my applications, it starts a debounce timer and then it uses a rolling average incremented and decremented by the pocket boolean value changing. this works well so far in testing, the variables are adjustable to.
in this configuration, the timer period is 10 msec, and if the switch is false it subtracts from the filter and if the switch is positive is increments the filter, the pocket number change can only be true if for 10 consecutive cycles the switch is either true or false. other wise the output will have to wait until one of them is true and as they can botr change the value from -10 to 0 to 10, it creates a weighted average based in input switch time. Think of it as duty cycle in 10% increments. once the duty cycle is -100% or +100% and the timer is greater than10 fperiod loops, then it updates the pocket number or it doesn't. better than a simple timer, avoids crazy filtering algorithms and solves noisy input problems, needs a watchdog timeout added for the case where the primary timer is greater than 250msec or some type of value , then fault out with a error for switch input noisy etc.
if (PocketFilterFlag == true){ // is flag true to start comparison value count
PocketFilter += fperiod; // set in milliseconds
}
if (pocketunfiltered != pocket){ // set flags and start comparison operator for new pocket value
timer8 = 0;
timer8 += fperiod; // increment timer in milliseconds
PocketFilterFlag = true; // set the flag
}else{
if (pocketunfiltered == pocket){ // cancel if pocket and pockunfiltered are the same and supress timer
timer8 -= fperiod; // flush timer
}
}
if (PocketFilter >= timer8){ // set new pocket value if the pocket value is euqal to or greater than unfiltered for more than 10 milliseconds consecutively
pocket = pocketunfiltered; // set pocket value
PocketFilterFlag = false; // clear flag
timer8 = 0; // flush timer
}
in this configuration, the timer period is 10 msec, and if the switch is false it subtracts from the filter and if the switch is positive is increments the filter, the pocket number change can only be true if for 10 consecutive cycles the switch is either true or false. other wise the output will have to wait until one of them is true and as they can botr change the value from -10 to 0 to 10, it creates a weighted average based in input switch time. Think of it as duty cycle in 10% increments. once the duty cycle is -100% or +100% and the timer is greater than10 fperiod loops, then it updates the pocket number or it doesn't. better than a simple timer, avoids crazy filtering algorithms and solves noisy input problems, needs a watchdog timeout added for the case where the primary timer is greater than 250msec or some type of value , then fault out with a error for switch input noisy etc.
if (PocketFilterFlag == true){ // is flag true to start comparison value count
PocketFilter += fperiod; // set in milliseconds
}
if (pocketunfiltered != pocket){ // set flags and start comparison operator for new pocket value
timer8 = 0;
timer8 += fperiod; // increment timer in milliseconds
PocketFilterFlag = true; // set the flag
}else{
if (pocketunfiltered == pocket){ // cancel if pocket and pockunfiltered are the same and supress timer
timer8 -= fperiod; // flush timer
}
}
if (PocketFilter >= timer8){ // set new pocket value if the pocket value is euqal to or greater than unfiltered for more than 10 milliseconds consecutively
pocket = pocketunfiltered; // set pocket value
PocketFilterFlag = false; // clear flag
timer8 = 0; // flush timer
}
Last edit: 12 Jan 2023 17:28 by smc.collins.
Please Log in or Create an account to join the conversation.
- smc.collins
- Offline
- Platinum Member
Less
More
- Posts: 676
- Thank you received: 117
12 Jan 2023 19:01 - 13 Jan 2023 03:46 #261725
by smc.collins
Replied by smc.collins on topic Toolchanger HAL Component project
Day3 of program build, I will need some folks to help debug and test code soon, if you know C or C or really any programming language, the help will be needed, this is going to be a 3000 line program most likely. I am trying to reusue as much debugged logic as I can to prevent bugs. a good bit of boiler plate and variable naming modification. the main portion of the control logic is flushed out, and because most all of it is the same, debugging 1 blocks fixes ALL of the execution blocks. Next up, I need to think on how to get from the end of the block to the tool changer and back again. I can get to the carousel but I need to think about how I am going to get back from the carousel pocket to the logic blocks. Need a day or so to think on that one. Feedback wanted if available. I will get started on a hal file shortly so people can experiment if they want to.
Last edit: 13 Jan 2023 03:46 by smc.collins.
Please Log in or Create an account to join the conversation.
Time to create page: 0.120 seconds