repetier / Repetier-Firmware

Firmware for Arduino based RepRap 3D printer.
813 stars 734 forks source link

dev2: ZProbe position problem when having dual extruder setup #991

Closed JoeScotty closed 4 years ago

JoeScotty commented 4 years ago

Hi,

trying to configure offset values for following configuration at a cartesian printer and came to varying ZProbing positions: This should be the final setup X to the right, Y up, Tool1 is at the lower left edge of the printable area:

               O ZProbe

        O Tool2       O Tool1                   

For test as a first step I used only negative offsets, because all tools and ZProbe are all reachable. So the test setup looks like this:

                          O Tool1                   
        O Tool2
               O ZProbe

Basic Parameters around offset topic: ENDSTOP_<X/Y>_BACK_ON_HOME = 0/0 <X/Y>min = 0/0 ZHOME<X/Y>_POS = 0/0

The issue is, that the probing position is not allways the position specified by Z-Probe<X/Y>Offset. Made a series of offset values, here is a screenshot of my test table: grafik

My interpretation: The X position, which is moved to for probing, is the mathematical smaller value of Tool2 X offset and ZProbe X offset The Y position, which is moved to for probing, is the mathematical smaller value of Tool2 Y offset and ZProbe Y offset

I already added log information in motionLevel1.cpp, void Motion1::setToolOffset(float ox, float oy, float oz) The transmittel values ox and oy seem to be wrong:

    Tool 1 -- offset (EEPROM) 0/0
    Tool 2 -- offset (EEPROM) -14/-4
    Z-probe X offset (EEPROM) -15/-23

    probing is at pos 15/23 (correct)
    log:
        16:15:23.508 : setToolOffset: TOffXalt=0.00 TOffYalt=0.00 OxNeu=15.00 OyNeu=23.00   XYHomed!   CurrPosX=0.00 CurrPosY=0.00 TempPosX (CurPosX+OxNeu-TOffXAlt)=15.00 TempPosY (CurPosY+OYNeu-TOffYAlt)=23.00
        16:15:24.060 : setToolOffset continued: TOffXNeu=15.00 TOffYNeu=23.00

    Tool 1 -- offset (EEPROM) 0/0
    Tool 2 -- offset (EEPROM) -16/-4
    Z-probe X offset (EEPROM) -15/-23

    probing is at pos 16/23 (not correct)
    log:
        16:26:04.067 : setToolOffset: TOffXalt=0.00 TOffYalt=0.00 OxNeu=16.00 OyNeu=23.00   XYHomed!   CurrPosX=0.00 CurrPosY=0.00 TempPosX (CurPosX+OxNeu-TOffXAlt)=16.00 TempPosY (CurPosY+OYNeu-TOffYAlt)=23.00
        16:26:04.626 : setToolOffset continued: TOffXNeu=16.00 TOffYNeu=23.00

Did I configure something wrong?

JoeScotty commented 4 years ago

Just saw: the first two coloumns in the prviuous post are Tool1. Sorry

In the meantime I added some more debug information

Offset-Values:

     Tool1            Tool2            Z-Probe
X Offs  Y Offs   X Offs  Y Offs   X Offs  Y Offs 
   0      0        -24     -4      -15     -23

physical probing position is 24/23, should be 15/23 in my mind.

The Log lines begins with file - function (class) - than Variables and values.

Intermediate Lines: my comments

    during homing X and Y
    16:10:32.967 : PrTypeCart-OfficToTransf: officialX (0.00) + tOffsX (0.00) =0.00   officialY (-317.00) + tOffsY (0.00) =-317.00
    16:10:32.967 : PrTypeCart-OfficToTransf: officialX (0.00) + tOffsX (0.00) =0.00   officialY (0.00) + tOffsY (0.00) =0.00
    16:10:32.967 : PrTypeCart-OfficToTransf: officialX (0.00) + tOffsX (0.00) =0.00   officialY (0.00) + tOffsY (0.00) =0.00

    next shows zProbe offsets
    16:10:32.970 : zprobe-ZPHandler-vor closestAllowed: OffX=-15.00 OffY=-23.00
    16:10:32.970 : zprobe-ZPHandler-nach closestAllowed: OffX=-15.00 OffY=-23.00

    I think the "9" in officialX should not be there. 9 is probably the distance between Tool2Xoffset and ZProbeXOffset
    16:10:32.971 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (0.00) =9.00   officialY (0.00) + tOffsY (0.00) =0.00
    16:10:32.971 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (0.00) =9.00   officialY (0.00) + tOffsY (0.00) =0.00
    16:10:32.971 : zprobe-ZPHandler-vor Aufruf setToolOffset: offsetX=15.00 OffY=23.00

    Here the wrong X probing position (24) is calculated.
    16:10:32.971 : setToolOffset: TOffXalt=0.00 TOffYalt=0.00 OxNeu=15.00 OyNeu=23.00   XYHomed!   CurrPosX=9.00 CurrPosY=0.00 TempPosX (CurPosX+OxNeu-TOffXAlt)=24.00 TempPosY (CurPosY+OYNeu-TOffYAlt)=23.00
    16:10:32.971 : PrTypeCart-OfficToTransf: officialX (24.00) + tOffsX (0.00) =24.00   officialY (23.00) + tOffsY (0.00) =23.00
    16:10:33.747 : setToolOffset continued: TOffXNeu=15.00 TOffYNeu=23.00
    16:10:33.747 : PrTypeCart-TransfToOfficials VOR OffsetManip: officialX (24.00  officialY (23.00
    16:10:33.748 : PrTypeCart-TransfToOfficials NACH OffsetManip: officialX (9.00  officialY (0.00
    16:10:33.751 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:33.751 : PrTypeCart-TransfToOfficials VOR OffsetManip: officialX (24.00  officialY (23.00
    16:10:33.751 : PrTypeCart-TransfToOfficials NACH OffsetManip: officialX (9.00  officialY (0.00
    16:10:34.758 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:35.571 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:35.623 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:36.081 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:37.045 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:37.076 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:38.135 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (0.00) + tOffsY (23.00) =23.00
    16:10:38.136 : PrTypeCart-OfficToTransf: officialX (24.00) + tOffsX (15.00) =39.00   officialY (4.00) + tOffsY (23.00) =27.00
    16:10:38.136 : setToolOffset: TOffXalt=15.00 TOffYalt=23.00 OxNeu=0.00 OyNeu=0.00   XYHomed!   CurrPosX=24.00 CurrPosY=4.00 TempPosX (CurPosX+OxNeu-TOffXAlt)=9.00 TempPosY (CurPosY+OYNeu-TOffYAlt)=-19.00
    16:10:38.137 : PrTypeCart-OfficToTransf: officialX (9.00) + tOffsX (15.00) =24.00   officialY (-19.00) + tOffsY (23.00) =4.00
    16:10:39.038 : setToolOffset continued: TOffXNeu=0.00 TOffYNeu=0.00
    16:10:39.039 : PrTypeCart-TransfToOfficials VOR OffsetManip: officialX (24.00  officialY (4.00
    16:10:39.039 : PrTypeCart-TransfToOfficials NACH OffsetManip: officialX (24.00  officialY (4.00
    16:10:39.039 : PrTypeCart-OfficToTransf: officialX (24.00) + tOffsX (0.00) =24.00   officialY (4.00) + tOffsY (0.00) =4.00
    16:10:39.730 : PrTypeCart-TransfToOfficials VOR OffsetManip: officialX (24.00  officialY (4.00
    16:10:39.731 : PrTypeCart-TransfToOfficials NACH OffsetManip: officialX (24.00  officialY (4.00
    16:10:39.731 : PrTypeCart-OfficToTransf: officialX (24.00) + tOffsX (0.00) =24.00   officialY (4.00) + tOffsY (0.00) =4.00
    16:10:39.732 : PrTypeCart-OfficToTransf: officialX (24.00) + tOffsX (0.00) =24.00   officialY (4.00) + tOffsY (0.00) =4.00

Hope this helps a bit!

repetier commented 4 years ago

I was already answering last post here but it is gone somehow. Your problem is in

void PrinterType::closestAllowedPositionWithNewXYOffset(float pos[NUM_AXES], float offX, float offY, float safety) {
    // offX and offY are with sign as stored in tool not when assigned later!
    float offsets[3] = { offX, offY, 0 };
    float tOffMin, tOffMax;
    for (fast8_t i = 0; i <= Z_AXIS; i++) {
        Tool::minMaxOffsetForAxis(i, tOffMin, tOffMax);

        float p = pos[i] - offsets[i];
        float minP = Motion1::minPos[i] + safety + tOffMax - tOffMin;
        float maxP = Motion1::maxPos[i] - Motion1::rotMax[i] - safety + tOffMax - tOffMin;
        if (p < minP) {
            pos[i] += minP - p;
        } else if (p > maxP) {
            pos[i] -= p - maxP;
        }
    }
}

I think. Currently I think I have an error in my math there. Just not sure exactly what I need to change to not make it break with dependent other code and transformations.

JoeScotty commented 4 years ago

...still working on it... First math model is there, built in excel, but still needs to define tests and pass tests....

repetier commented 4 years ago

Ok I think I got it. New version is online and my tests seem to be working now after having problems at the start. If you see there are still wrong positions let me know.

JoeScotty commented 4 years ago

Hi, sorry to say I have bad news: I tested the changes from Oct 14th and the probing positions were not as expected. In one line you deleted the " + tOffMax" while tOffMax was 0 in some of my tests.

Here is the result table for some tests cases (see also description in earlier post):

grafik

But I have reached a certain level in my math experiments that gave good results for my test setup, at least up to now ;-) (cartesian, 0/0 at front left, dual extruder, BLTouch) but I don't know if the results are valid for other scenarios, too.

I want to share my thought in developing the formulas and code while hoping it will help:

Preconditions/Assumptions

  1. Tool1 has Offset 0/0
  2. The whole printing area , defined by X_Min, Y_Min, X_Max, Y_Max, can be reached by both tools. This means, the physical size of the reachable positions is bigger than just X_Max - X_Min (same for Y)

Here is how I came to my math (So you can see if I missed something) The variable names refer to the names you used.
You are calculating with the X-Position of the smallest ToolOffsetX (->tOffMin) and with the X-Position of the biggest ToolOffsetX (->tOffMax)

The reachable area for ZProbe:
    First let's focus on the area with small X Positions, which are the left side of the bed, if 0/0 ist front left 
        The ZProbe can reach all X Positions in the printing area in the following cases.
            O      O  O
            T2     ZP T1

            or

            O    O    O
            ZP   T2   T1

        As first formula
              ZPOffsX < tOffMax

        Including the Z_PROBE_BORDER (=safety variable)
            ZPOffsX + safety < tOffMax

        Including the current X-Position (the bigger the X-Positions, the "easier" the ZProbe can reach this Position.
        The distance between the current X-Position and the end of the reachable area is PosX - MinX
            ZPOffsetX + safety - (PosX -MinX) < tOffMaxX

        A Position correction is needed if
            ZPOffsetX + safety - (PosX -MinX) > tOffMaxX
        In this case the correction value is
            ZPOffsetX + safety - (PosX -MinX) - tOffMaxX

    In case of X-Positions close to Max_X:
        A Position correction is needed if
            ZPOffsetX - safety + (MaxX - PosX) < tOffMinX
        In this case the correction value is
            ZPOffsetX - safety + (MaxX - PosX) - tOffMinX

    Same for Y and Z

Here are some other setups and correction areas which I tested:

grafik

This is the code:

void PrinterType::closestAllowedPositionWithNewXYOffset(float pos[NUM_AXES], float offX, float offY, float safety) {
    float offsets[3] = { offX, offY, 0 };
    float tOffMin, tOffMax;
    for (fast8_t i = 0; i <= Z_AXIS; i++) {
        Tool::minMaxOffsetForAxis(i, tOffMin, tOffMax);
        float minP = offsets[i] + safety - pos[i] + Motion1::minPos[i];
        float maxP = offsets[i] - safety - pos[i] + Motion1::maxPos[i];
        if (minP > tOffMax) {
            pos[i] += minP - tOffMax;
        } else if (maxP < tOffMin) {
            pos[i] += maxP - tOffMin;
        }
    }
}

I doubt this covers all scenarios you have to care about, but I hope i helps a bit.

JoeScotty commented 4 years ago

One minor thing is still open. Saw this when using G30 and don't know, how essential this is, but just wanted to share:

In ZProbeHandler::activate() PrinterType::closestAllowedPositionWithNewXYOffset(cPos, offsetX, offsetY, Z_PROBE_BORDER) is called, where cPos is changed if an unallowed ZProbing position will be avoided.

I think in ZProbeHandler::deactivate() the cPos change should be reversed . Otherwise the tool position after probing is changed compared to the tool position before probing.

Regards

JoeScotty commented 4 years ago

This worked for me:

In zprobe, #if Z_PROBE_TYPE == Z_PROBE_TYPE_BLTOUCH, add declarations:

float cPos_before_probing[NUM_AXES];

In void ZProbeHandler::activate(), before closestAllowedPositionWithNewXYOffset...

    Motion1::copyCurrentOfficial(cPos);

    // Save Position before possible Position Correction due to unallowed area for ZProbe
    for (fast8_t i = 0; i < Z_AXIS; i++) {
        cPos_before_probing[i] = cPos[i];
    }

    PrinterType::closestAllowedPositionWithNewXYOffset(cPos, offsetX, offsetY, Z_PROBE_BORDER);

In void ZProbeHandler::deactivate(), after setToolOffset...

    Motion1::moveByOfficial(cPos, Motion1::moveFeedrate[X_AXIS], false);
    Motion1::setToolOffset(-tool->getOffsetX(), -tool->getOffsetY(), -tool->getOffsetZ());

    //Undo of possible Position Correction (because of unallowed ZProbe Positions), restore Position before probing
    for (fast8_t i = 0; i < Z_AXIS; i++) {
        cPos[i] = cPos_before_probing[i]; 
    }

    Motion1::moveByOfficial(cPos, Motion1::moveFeedrate[X_AXIS], false);

    // inform also Repetier Host about new position coordinates
    Motion1::printCurrentPosition();

    activated = false;
    Printer::setZProbingActive(false);
repetier commented 4 years ago

Ok, new try to get it into my mind correctly. We only need to consider x axis since we are in a loop and each axis has same constrain problems. There is no cross reference to other axis here.

Global position allowed is minPos..maxPos. During homing we add an extra move of tOffMax for min homing and tOffMin for max homing. That position is assigned 0 offset. Now we can assign the tool with tOffMax which gets set as negative offset so it is back at start or we assign tOffMin so it moves to the right.

So in transformed coordinates the limits including assigned offsets are minPos-tOffMax+safety ... maxPos-tOffMin-safety That is a bit counter intuitive to have max terms on min side is I think part of my problems making it all up.

Now the transformed position we want to take up is pos-offsets so we have constraints minPos-tOffMax+safety < pos-offsets < maxPos-tOffMin-safety

Leta take tool offset -10 and 15 and minPos=0 and maxPos=100 and safety 0 so we have -15 ... 110 as allowed offset.

X      ZPOffset    Pos wanted   NewX corrected
0      -20           20              0
0       20          -20              5
100    -20          120             90
100     20           80              100

minPos-tOffMax+safety = minP < pos-offsets = p => offsets+safety-pos+minPos < tOffMax

which is your equation. I just find the approach counter intuitive to understanding the correction also correct. So my preferred way to write it down and understand is

void PrinterType::closestAllowedPositionWithNewXYOffset(float pos[NUM_AXES], float offX, float offY, float safety) {
    // offX and offY are with sign as stored in tool not when assigned later!
    // pos is in official coordinate system
    float offsets[3] = { offX, offY, 0 };
    float tOffMin, tOffMax;
    for (fast8_t i = 0; i <= Z_AXIS; i++) {
        Tool::minMaxOffsetForAxis(i, tOffMin, tOffMax);

        float p = pos[i] - offsets[i];
        float minP = Motion1::minPos[i] + safety - tOffMax;
        float maxP = Motion1::maxPos[i] - safety + tOffMin;
        if (p < minP) {
            pos[i] += minP - p;
        } else if (p > maxP) {
            pos[i] -= p - maxP;
        }
    }
}

Quite complicated so many thanks for pointing me to the error. This also revealed other errors which are already fixed. Will adjust the code and make an update soon.

Regarding your back to original position I will about it. This creates new edge cases like:

On the other side it also has some appeal if position stays same after deactivating.

JoeScotty commented 4 years ago

It's good to see that, if we start from different points of view, the same result is reached.

Please have another look at the maxP line. If I change my equation for the max area to your format, it should be

      float maxP = Motion1::maxPos[i] - safety - tOffMin;

In my tests it was successfull, but it was only for certain scenarios.

Regarding back to original: If it did not return to the previous position, the shown position in Repetier Host matched the physical position. So after the following move both options should be the same.

I can imagine considering all options and variations when changing some code is a really complex matter.

repetier commented 4 years ago

Yes, of course you are right. I even wrote it my self before the code: Now the transformed position we want to take up is pos-offsets so we have constraints minPos-tOffMax+safety < pos-offsets < maxPos-tOffMin-safety

Should better read my own equations. Thanks.