%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% phiCAD2NC %%% %%% Skeletal Plans %%% %%% Michael Sintek First Version: August 1991 %%% %%% Harold Boley, Markus Perling Current Version: June 1997 %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Input: classified workpieces % ---------------------------- % class-wp ::= cwp[,] % globals ::= "global annotations; currently just the max radius; % could additionally contain the material and the % surface quality" % feature-list ::= [ { }* ] % nested-feature ::= nft[,] % feature ::= | | | ... % leftshoulder ::= lsh[,] % rightshoulder :: rsh[,] % groove ::= grv[,,] % flank ::= flk[] % ground ::= grd[] % coordinates ::= [ { }* ] % point ::= p[,] % z-coordinate and radius % Output: skeletal plans % ---------------------- % skeletal-plan ::= skp[,] % % sac = sequential/alternative/commutative % plan ::= [] % empty plan % | % atomic action % | seq[] % sequential % | com[] % commutative % | alt[] % alternative % plan-list ::= [ { }* ] % action ::= | | ... % roughing ::= roughing[,,] % tool ::= tool[,] % way ::= left | right % means: working into this direction % geometry ::= geo[] % cf. input % 1. create skeletal plan % ======================= skeletal-plan(cwp[Globals,Features]) :- Skp .= skp/com(Features) & skp[Globals,Skp]. % skp/com % ------- skp/com([]) :& []. skp/com([H|T]) :& norm-com(skp/cfeat(H),skp/com(T)). % skp/cfeat (complex features like nft = nested feature) % ------------------------------------------------------ skp/cfeat(nft[Feat,Refined-feat]) :& norm-seq(skp/feat(Feat),skp/com(Refined-feat)). % additional complex/nested features ... % skp/feat (for unnested features like lsh, rsh, grv) % --------------------------------------------------- skp/feat(lsh[flk[Flank],grd[Ground]]) :& skp/lsh(Flank,Ground). skp/feat(rsh[grd[Ground],flk[Flank]]) :& skp/rsh(Ground,Flank). skp/feat(grv[flk[Flank1],grd[Ground],flk[Flank2]]) :& skp/grv(Flank1,Ground,Flank2). % skeletal plans for unnested features % ------------------------------------ % workpiece material and quality (currently just global constants): wp-material() :& high-alloy-steel. quality() :& normal. % skp/lsh % ------- skp/lsh(Flank,Ground) :- Fl-gr .= append-coord(Flank,Ground), tool-sel(roughing, wp-material(), quality(), 0, rf-max(compute-flank-angles(Flank)), left, Tools) & check-alternatives(gen-roughing-alternatives(Tools,left,geo[Fl-gr])). % skp/rsh % ------- skp/rsh(Ground,Flank) :- Gr-fl .= append-coord(Ground,Flank), tool-sel(roughing, wp-material(), quality(), 0, rf-max(compute-flank-angles(reverse-coord(Flank))), right, Tools) & check-alternatives(gen-roughing-alternatives(Tools,right,geo[Gr-fl])). % skp/grv % ------- skp/grv(Flank1,Ground,Flank2) :- Fl-gr-fl .= append-coord(Flank1,append-coord(Ground,Flank2)), Max1 .= rf-max(compute-flank-angles(Flank1)), Max2 .= rf-max(compute-flank-angles(reverse-coord(Flank2))), tool-sel(roughing,wp-material(),quality(),Max1,Max2,right,Tools1), tool-sel(roughing,wp-material(),quality(),Max2,Max1,left,Tools2), Right-alt .= check-alternatives(gen-roughing-alternatives(Tools1, right, geo[Fl-gr-fl] )), Left-alt .= check-alternatives(gen-roughing-alternatives(Tools2, left, geo[Fl-gr-fl]) ) & norm-alt(norm-seq(Left-alt,Right-alt),norm-seq(Right-alt,Left-alt)). % additional skeletal plans ... % tool-sel (tool selection) % ------------------------- % format: % tool-sel(,,,,,, % [ { [ ] }+ ]) % precomputed tool-selection facts ... % tool selection: tool-sel(roughing, high-alloy-steel, normal, Alpha, Beta, left, % [[dnmm-71,tmaxp-pdl93],[rcmx,tmaxp-prl40]]). [[rcmx,tmaxp-prl40]]). tool-sel(roughing, high-alloy-steel, normal, Alpha, Beta, right, [[dnmm-71,tmaxp-pdr93],[rcmx,tmaxp-prr40]]). % append-coord % ------------ append-coord([],F) :& F. append-coord(F,[]) :& F. append-coord([p[Z,R]],[p[Z,R]|Rest]) :& [p[Z,R]|Rest]. append-coord([H|T],R) :& tup(H|append-coord(T,R)). % reverse-coord % ------------- reverse-coord([]) :& []. reverse-coord([p[Z,R]|Rest]) :- Mirr-z .= -(0,Z) & appfun(reverse-coord(Rest),[p[Mirr-z,R]]). % compute-flank-angles (only for descending flanks) % ------------------------------------------------- compute-flank-angles([]) :& []. compute-flank-angles([p[Z,R]]) :& []. compute-flank-angles([p[Z,R1],p[Z,R2]|Rest]) :& % 90 deg ring tup(90|compute-flank-angles([p[Z,R2]|Rest])). compute-flank-angles([p[Z1,R1],p[Z2,R2]|Rest]) :& tup(rad2rounded-deg(atan(/(-(R1,R2),-(Z2,Z1))))| compute-flank-angles([p[Z2,R2]|Rest])). rad2rounded-deg(Rad) :& *(round(/(+(*(Rad,57.29577951308232),2.9999),3)),3). % gen-roughing-alternatives % ------------------------- gen-roughing-alternatives([],Way,Geo) :& []. gen-roughing-alternatives([[Tool,Holder]|Rest],Way,Geo) :& norm-alt(roughing[tool[Tool,Holder],Way,Geo], gen-roughing-alternatives(Rest,Way,Geo)). % check-alternatives % ------------------ check-alternatives([]) :& rf-format("tool selection unsuccessful"). check-alternatives(X) :& X. % 2. skp access/transform functions % ================================= % a) get-skp-top % -------------- get-skp-top(skp[Globals,Sac-plan]) :& skp-top/plan(Sac-plan). skp-top/plan([]) :& []. skp-top/plan(com[Com]) :& skp-top/com(Com). skp-top/plan(seq[Seq]) :& skp-top/seq(Seq). skp-top/plan(alt[Alt]) :& skp-top/alt(Alt). skp-top/plan(Action) :& Action. skp-top/com([]) :& []. skp-top/com([H|T]) :& norm-com(skp-top/plan(H),skp-top/com(T)). skp-top/seq([]) :& []. skp-top/seq([H|T]) :& skp-top/plan(H). skp-top/alt([]) :& []. skp-top/alt([H|T]) :& norm-alt(skp-top/plan(H),skp-top/alt(T)). % b) execute-skp-action % --------------------- % skp-exec-action: skp-exec-action(,) % -> [,,] % -------------------------------------------------------- skp-exec-action(skp[Globals,Sac-plan],Actspec) :- [Actions,Rest-plan,Costs] .= skp-exec/plan(Sac-plan,Actspec) & [Actions,skp[Globals,Rest-plan],Costs]. skp-exec/plan([],Actspec) :& [[],[],0]. skp-exec/plan(com[Com],Actspec) :& skp-exec/com(Com,Actspec). skp-exec/plan(seq[Seq],Actspec) :& skp-exec/seq(Seq,Actspec). skp-exec/plan(alt[Alt],Actspec) :& skp-exec/alt(Alt,Alt,Actspec). skp-exec/plan(Action,Actspec) :& skp-exec/act(Action,Actspec). skp-exec/com([],Actspec) :& [[],[],0]. skp-exec/com([H|T],Actspec) :- [H-actions,H-rest-plan,H-costs] .= skp-exec/plan(H,Actspec), [T-actions,T-rest-plan,T-costs] .= skp-exec/com(T,Actspec) & tup(appfun(H-actions,T-actions), norm-com(H-rest-plan,T-rest-plan), +(H-costs,T-costs)). skp-exec/seq([],Actspec) :& [[],[],0]. skp-exec/seq([H|T],Actspec) :& skp-exec/seq1(skp-exec/plan(H,Actspec),T,Actspec). skp-exec/seq1([H-actions,[],H-costs],T,Actspec) :- [T-actions,T-rest-plan,T-costs] .= skp-exec/com(T,Actspec) & tup(appfun(H-actions,T-actions),T-rest-plan,+(H-costs,T-costs)). skp-exec/seq1([H-actions,H-rest-plan,H-costs],T,Actspec) :& tup(H-actions,norm-seq(H-rest-plan,norm-rest-seq(T)),H-costs). skp-exec/alt(Alt,[],Actspec) :& % no more alternatives to check [[],alt[Alt],0]. skp-exec/alt(Alt,[H|T],Actspec) :& skp-exec/alt1(Alt,skp-exec/plan(H,Actspec),H,T,Actspec). skp-exec/alt1(Alt,[H-actions,H,Costs],H,T,Actspec) :& skp-exec/alt(Alt,T,Actspec). % try remaining alternatives skp-exec/alt1(Alt,[H-actions,H-rest-plan,H-costs],H,T,Actspec) :& [H-actions,H-rest-plan,H-costs].% alternative found skp-exec/act(roughing[Tool,Way,Geo],Tool) :& [[roughing[Tool,Way,Geo]],[],1].% costs: 1 skp-exec/act(Action,Actspec) :& [[],Action,0]. % (c) extract-actions: extract-actions() % ------------------------------------------------ extract-actions([]) :& []. extract-actions(com[Com]) :& extract-actions/list(Com). extract-actions(seq[Seq]) :& extract-actions/list(Seq). extract-actions(alt[Alt]) :& extract-actions/list(Alt). extract-actions(Action) :& [Action]. extract-actions/list([]) :& []. extract-actions/list([H|T]) :& appfun(extract-actions(H),extract-actions/list(T)). % (d) get-tools (from action-list; removing duplicates) % ----------------------------------------------------- get-tools([]) :& []. get-tools([roughing[Tool,Way,Geo]|Rest]) :- Rest-tools .= get-tools(Rest) & add-if-new(Tool,Rest-tools). % (e) count-com-actions % --------------------- count-com-actions(skp[Globals,Sac-plan]) :& cca/plan(Sac-plan). cca/plan([]) :& 0. cca/plan(com[Com]) :& cca/com(Com). cca/plan(seq[[H|T]]) :& cca/plan(H). cca/plan(alt[[H|T]]) :& % only consider first alternative cca/plan(H). cca/plan(Action) :& 1. cca/com([]) :& 0. cca/com([H|T]) :& +(cca/plan(H),cca/com(T)). % 3. skp normalizations % ===================== % norm-com: norm-com(,) % ------------------------------------ norm-com([],Plan) :& Plan. norm-com(Plan,[]) :& Plan. norm-com(com[Com1],com[Com2]) :- Com12 .= appfun(Com1,Com2) & com[Com12]. norm-com(Plan,com[Com]) :& com[[Plan|Com]]. norm-com(com[Com],Plan) :- Cp .= appfun(Com,[Plan]) & com[Cp]. norm-com(Plan1,Plan2) :& com[[Plan1,Plan2]]. % norm-seq: norm-seq(,) and norm-rest-seq() % --------------------------------------------------------------- norm-seq([],Plan) :& Plan. norm-seq(Plan,[]) :& Plan. norm-seq(seq[Seq1],seq[Seq2]) :- Seq12 .= appfun(Seq1,Seq2) & seq[Seq12]. norm-seq(Plan,seq[Seq]) :& seq[[Plan|Seq]]. norm-seq(seq[Seq],Plan) :- Sp .= appfun(Seq,[Plan]) & seq[Sp]. norm-seq(Plan1,Plan2) :& seq[[Plan1,Plan2]]. % norm-rest-seq() : expects to be the rest of a normalized sequence norm-rest-seq([]) :& []. norm-rest-seq([Plan]) :& Plan. norm-rest-seq(Tup) :& seq[Tup]. % norm-alt: norm-alt(,) % ------------------------------------ norm-alt([],Plan) :& Plan. norm-alt(Plan,[]) :& Plan. norm-alt(alt[Alt1],alt[Alt2]) :- Alt12 .= appfun(Alt1,Alt2) & alt[Alt12]. norm-alt(Plan,alt[Alt]) :& alt[[Plan|Alt]]. norm-alt(alt[Alt],Plan) :- Ap .= appfun(Alt,[Plan]) & alt[Ap]. norm-alt(Plan1,Plan2) :& alt[[Plan1,Plan2]]. % 4. skp auxiliaries % ================== % add-if-new % ---------- add-if-new(Tool,Rest-tools) :- rf-member(Tool,Rest-tools) & Rest-tools. add-if-new(Tool,Rest-tools) :& [Tool|Rest-tools]. % find-pos % -------- find-pos(Element,List) :& find-pos1(Element,List,0). find-pos1(Element,[Element|Rest],No) :& No. find-pos1(Element,[H|T],No) :& find-pos1(Element,T,1+(No)).