Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Help needed to automate use of Peanut 2 connectors in Fusion 360

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
faeluke
226 Views, 4 Replies

Help needed to automate use of Peanut 2 connectors in Fusion 360

I have a use case for the Peanut 2 connector in some woodworking projects. I would like to automate the CAM process. The most attractive solution is to insert holes into my model in the design environment. In the manufacturing environment, I would like to have a custom 3d tool path added to the UI that allows me to select the holes, set a direction for the slot, and inserts the correct G-code into the output file. Is this possible? 

 
 
In the linked file, the mahogany bench will be assembled to the upper and lower cabinets using the Peanut 2 product. I may have exaggerated the need for 80 in this design, but this part alone requires 24. I would expect the final number to top more than 56. 
 
Please note that the hole that defines the end of the tool path also defines the location of the peanut.
Ideal process
Setup 1: Top of board
Select the correct tool
Select a hole on the top
click on a check box that selects all same-size holes
assign a direction for the slot
Run the post process and the code is created that will end the slot at the hole location and orient the slot as identified in the custom dialog box for each hole instance.
Setup 2: Bottom of board
Repeat the functions of Setup 1 for the new orientation of the workpiece
 
The picture below shows the tool path. Note that the slot ends at the position where the hole is drawn in the fusion sketch to properly locate the peanut connector in the cabinet pieces above and below the bench.
 
Any and all help would be greatly appreciated!
 
faeluke_0-1691149713784.png

 

 

 

4 REPLIES 4
Message 2 of 5
Jorge_Jaramillo
in reply to: faeluke

@Jorge_Jaramillo - this post is being edited to remove PII.

 

Hi @faeluke ,

 

I believe I could help you with this development.

I was checking your design and I couldn't see where holes need to be placed.  Could you clarify that?

The image with the instructions on how the tool paths need to be done is clear.

 

Best regards,

Jorge Jaramillo

 

 

Message 3 of 5
faeluke
in reply to: Jorge_Jaramillo

@Jorge_Jaramillo 

Jorge,

The last sketch and the two extrudes that follow identify the location of the holes. They do not identify the start of the tool path, they identify the end of the tool path. The holes are 6mm, and the extrusions are bidirectional to set the location of the corresponding mechanical connector. 

 

What do you suggest?

Message 4 of 5
Jorge_Jaramillo
in reply to: faeluke

@Jorge_Jaramillo - this post is being edited to remove PII.

 

Hi @faeluke ,

 

I was able to generate the toolpath required with a custom code in the post processor, based on a drilling operation.

This is step by step of the implementation:

 

1.  Create a group of parameters for the NC program and the operation to select the type of slot required, the orientation of the slot and the distances in every step of the slot:

wtallerdemadera_0-1691380183789.png

wtallerdemadera_1-1691380299054.png

 

This way the parameters could be supplied to the post processor from the operation itself or from the NC program.

 

This is the code to add the parameters to the post processor:

 

properties = {
...
  drillConnector1Type: {
    title      : "Connector type",
    description: "Select if the drilling operation is for a connector",
    group      : "drillingConnector",
    type       : "enum",
    values     : [
      {title:"None", id:"None"},
      {title:"Peanut2", id:"Peanut2"},
    ],
    value: "Peanut2",
    scope: ["post", "operation"],
    enabled: "drilling"
  },
  drillConnector2Direction: {
    title      : "Entry path direction from ...",
    description: "Select your desired entry path direction",
    group      : "drillingConnector",
    type       : "enum",
    values     : [
      {title:"X-", id:"X-"},
      {title:"X+", id:"X+"},
      {title:"Y-", id:"Y-"},
      {title:"Y+", id:"Y+"}
    ],
    value: "X+",
    scope: ["post", "operation"],
    enabled: "drilling"
  },
  drillConnector4InitialPlunge: {
    title      : "Initial plunge (mm)",
    description: "Initial plunge on entry point",
    group      : "drillingConnector",
    type       : "number",
    value: 12.2,
    range: [1,15],
    scope: ["post", "operation"],
    enabled: "drilling"
  },
  drillConnector5AdditionalPlunge: {
    title      : "Additional plunge (mm)",
    description: "Additional plunge while creating the slot",
    group      : "drillingConnector",
    type       : "number",
    value: 2.1,
    range: [1,5],
    scope: ["post", "operation"],
    enabled: "drilling"
  },
  drillConnector6AdditionalTravel: {
    title      : "Additional travel (mm)",
    description: "Additional travel while making additional plunge to reach slot bottom",
    group      : "drillingConnector",
    type       : "number",
    value: 10,
    range: [1,20],
    scope: ["post", "operation"],
    enabled: "drilling"
  },
  drillConnector7FinalTravel: {
    title      : "Final travel (mm)",
    description: "Final travel at the slot bottom",
    group      : "drillingConnector",
    type       : "number",
    value: 10,
    range: [1,20],
    scope: ["post", "operation"],
    enabled: "drilling"
  },
...

 

 

2. Adding the "drillConnector2Direction" parameter allows it to choose the direction the slot is started and its orientation:

X-  : from left to right on the X axle

X+ : from right to left on the X axle

Y- : from the front to the back on the Y axle

Y+ : from the back to the front on the Y axle

 

3. Then the parameters are read into variables and X and Y offset are calculated according to the direction parameter. This in done inside the onOpen() funtion:

 

function onOpen() {
...
  // get parameters for drilling connectors slots
  drillConnector1Type = getProperty("drillConnector1Type")
  if (drillConnector1Type == "None") {
    writeComment("Drill slots connectors __disabled__")
  } else {
    writeComment("Drill slots connectors __enabled__ "+drillConnector1Type+" "+getProperty("drillConnector2Direction"))
    drillConnector4InitialPlunge = getProperty("drillConnector4InitialPlunge")
    drillConnector5AdditionalPlunge = getProperty("drillConnector5AdditionalPlunge")
    var drillConnector6AdditionalTravel = getProperty("drillConnector6AdditionalTravel")
    var drillConnector7FinalTravel = getProperty("drillConnector7FinalTravel")
    switch (getProperty("drillConnector2Direction")) {
      case "X-":
        dc_inic_x = -drillConnector6AdditionalTravel - drillConnector7FinalTravel
        dc_adic_x = -drillConnector6AdditionalTravel
        dc_inic_y = 0
        dc_adic_y = 0
        break;
      case "X+":
        dc_inic_x = drillConnector6AdditionalTravel + drillConnector7FinalTravel
        dc_adic_x = drillConnector6AdditionalTravel
        dc_inic_y = 0
        dc_adic_y = 0
        break;
      case "Y-":
        dc_inic_x = 0
        dc_adic_x = 0
        dc_inic_y = -drillConnector6AdditionalTravel - drillConnector7FinalTravel
        dc_adic_y = -drillConnector6AdditionalTravel
        break;
      case "Y+":
        dc_inic_x = 0
        dc_adic_x = 0
        dc_inic_y = drillConnector6AdditionalTravel + drillConnector7FinalTravel
        dc_adic_y = drillConnector6AdditionalTravel
        break;
    }
  }
...

 

 

4. To add a function to generate the G-CODE needed to make the slot:

 

function drillConnector(x, y, cycle) {
    switch (drillConnector1Type) {
        case "Peanut2":
            writeBlock(
                gAbsIncModal.format(90),
                gMotionModal.format(1),
                xOutput.format(x + dc_inic_x),
                yOutput.format(y + dc_inic_y),
                zOutput.format(cycle.retract),
                feedOutput.format(cycle.feedrate)
            );
            writeBlock(
                gAbsIncModal.format(90),
                zOutput.format(dc_stock_z_high-drillConnector4InitialPlunge),
                feedOutput.format(cycle.plungeFeedrate)
            );
            writeBlock(
                gAbsIncModal.format(90),
                xOutput.format(x + dc_adic_x),
                yOutput.format(y + dc_adic_y),
                zOutput.format(dc_stock_z_high-drillConnector4InitialPlunge-drillConnector5AdditionalPlunge)
            );
            writeBlock(
                gAbsIncModal.format(90),
                xOutput.format(x),
                yOutput.format(y)
            );
            writeBlock(
                gAbsIncModal.format(90),
                xOutput.format(x + dc_inic_x),
                yOutput.format(y + dc_inic_y),
                feedOutput.format(cycle.retractFeedrate)
            );
            writeBlock(
                gAbsIncModal.format(90),
                zOutput.format(cycle.retract)
            );
            break;
    }
}

 

 

5. Call the previous defined function instead of the current drilling translation.  This is done inside the onCyclePoint() function where the post processor make the drilling operation on the (x,y,z) coordinates provided from the design.

So this modification use the (x,y) coordinates as the target position of the connector and the offsets previously calculated are added to this coordinates to define the slot toolpath:

 

function onCyclePoint(x, y, z) {
  if (DEBUG)
    writeComment('__onCyclePoint  x '+x+' y '+y+' z '+z)

...

    switch (cycleType) {
    case "drilling":
// DRILL CONNECTOR SLOT >>>>
      if (drillConnector1Type == "None") {
// DRILL CONNECTOR SLOT <<<<
        writeBlock(
          gRetractModal.format(98), gAbsIncModal.format(90), gCycleModal.format(81),
          getCommonCycle(x, y, z, cycle.retract),
          feedOutput.format(F)
        );
// DRILL CONNECTOR SLOT >>>>
      } else {
        drillConnector(x, y, cycle)
      }
// DRILL CONNECTOR SLOT <<<<
      break;

...

  } else {
// DRILL CONNECTOR SLOT >>>>
    if (drillConnector1Type == "None") {
// DRILL CONNECTOR SLOT <<<<
      if (cycleExpanded) {
        expandCyclePoint(x, y, z);
      } else {
        writeBlock(xOutput.format(x), yOutput.format(y));
      }
// DRILL CONNECTOR SLOT >>>>
    } else {
      drillConnector(x, y, cycle)
    }
// DRILL CONNECTOR SLOT <<<<
  }
}

 

 

The following image there is the design I used to test it, where you can see 5 drilling operations:

wtallerdemadera_2-1691381807587.png

 

As a result this is the toolpath generated:

wtallerdemadera_6-1691382704270.jpeg

 

This is GCODE generated:

 

(1001)
(T1  D=3.175 CR=0. - ZMIN=14. - FLAT END MILL)
(DRILL SLOTS CONNECTORS __ENABLED__ PEANUT2 X)
G90 G94 G91.1 G40 G49 G17
G21
(DC_STOCK_Z_HIGH 18)

(DRILL1)
M5
T1
(  OPERATION_CYCLETYPE  DRILLING)
S18000 M3
G54
G0 X30. Y70.
G43 Z33. H1
(__ONCYCLEPOINT  X 30 Y 70 Z 14)
Z23.
G1 X50. F600.
Z5.8
X40. Z3.7
X30.
X50.
Z23.
(__ONCYCLEPOINT  X 70 Y 70 Z 14)
X90.
Z5.8
X80. Z3.7
X70.
X90.
Z23.
(__ONCYCLEPOINT  X 50 Y 50 Z 14)
X70. Y50.
Z5.8
X60. Z3.7
X50.
X70.
Z23.
(__ONCYCLEPOINT  X 70 Y 30 Z 14)
X90. Y30.
Z5.8
X80. Z3.7
X70.
X90.
Z23.
(__ONCYCLEPOINT  X 30 Y 30 Z 14)
X50.
Z5.8
X40. Z3.7
X30.
X50.
Z23.
G0 X30. Z33.

M30

 

 

 

I hope this could help to your project.

 

Best regards,

Jorge Jaramillo

 

Message 5 of 5
faeluke
in reply to: Jorge_Jaramillo

@Jorge_Jaramillo 

 

I can not thank you enough for turning this around so quickly and with such detail. I will update my post processor this weekend and attempt to make some chips. Truly excellent work!

 

Pictures to follow...

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report