Grade control

Right now the cut delta is calculated only with the closest survey point but it should be easy to calculate a weighted average from the 3 closest points with their relative distance from the blade. this will add a lot more accuracy and probably give the possibility to level with only a few survey points.

1 Like

Now this looks good already! Maybe we should merge some of these into the branch we have in github now?

The -1 elevation are coming from the exported file, since it’s missing some data for some points falling outside the boundary, need to take care of that in the conversion script. Some points just have the proposed elevation value, but not the original elevation so as a quick & dirty fix I replaced all NaN values with -1 in the script…

1 Like

So I wrote a parser to convert the contour.agd file directly into Opengrade. The file below does get it in there. Now the simulator appears not to like any longitude east of -100. I’ve reset it in the software and have come up with nothing. -85 = -850, 22 = -220. I have no idea. This is an @BrianTee_Admin question. I’m betting it has something to do with the zones, but??? So, I just had Opengrade “fix” your lat and lon to appear in the window. Actual GPS numbers may be different. Here is how I fixed it.

double lat = Convert.ToDouble(words[0])-8.86857358;
double lon = Convert.ToDouble(words[1])-133.507383;

Here is the code. I simply just replaced the contour section of the field opening in the SaveOpen.Designer.cs around line 390.

Word on caution, make sure the contour.agd file does not have any extra lines at the bottom.

load-agd.txt (3.2 KB)

And here is the contour file saved during the closing.

Contour.txt (21.6 KB)

Edit:
Doing some more code edit. The following is a picture of a little different concept. As you are driving it looks straight ahead and finds the closest points in a straight line and then creates and on the fly updated profile in the bottom window. This is showing following an ABline and the profile of both the land and the cut in that direction. I’m still working on getting the up and down blade indicator working for these points.

image

3 Likes

As for the AGD, I figured only the 3GP labeled points are the design points, there’s some boundary points etc with the other labels. Worked a bit with the shapefile but the lat/lon in that one are way off from the agd file, maybe some problem with opensurface settings.

Now this is really nice!

1 Like

Assembled a minimal PCB on one of the Kaupoimodv2 boards I had on stock. Neat setup all in all, A/D converter can be added and the +5 volt supply in the future for a draft sensor.

image

2 Likes

Hi
I tried to make a painted elevation map but I am stuck right now
opengrade3D

So, when I open a field it look min and max easting and northing. After, it make a new list with a point a each meter and for this point it should give the altitude for the nearest survey point. But right now it always take the last, I cannot find the bug.
OpenGL.Designer Line 676 CalculateMinMaxEastNort

 private void CalculateMinMaxEastNort()
        {


            eastingMin = 9999999;
            eastingMax = -9999999;
            northingMin = 9999999;
            northingMax = -9999999;

            int cnt = ct.ptList.Count;

            if (cnt > 0)
            {
                for (int i = 0; i < cnt; i++)
                {
                    //double x = i;
                    double y = ct.ptList[i].easting;
                    double z = ct.ptList[i].northing;

                    //find min max coordonates
                    if (eastingMin > y) eastingMin = y;
                    if (eastingMax < y) eastingMax = y;
                    if (northingMin > z) northingMin = z;
                    if (northingMax < z) northingMax = z;
                }
            }

            if (eastingMax == -9999999 | eastingMin == 9999999 | northingMax == -9999999 | northingMin == 9999999)
            {
                eastingMin = 0; eastingMax = 0; northingMax = 0; northingMin = 0;
            }
            else
            {
                eastingMin -= 2; eastingMax += 2; northingMax += 2; northingMin -= 2;
            }

            for (double h = (double)eastingMin; h < (double)eastingMax; h++)
            {
                for (double i = (double)northingMin; i < (double)northingMax; i++)
                {

                    int ptCnt = ct.ptList.Count;

                    if (ptCnt > 0)
                    {
                        int closestPointMap = 0;
                        int ptCount = ct.ptList.Count - 1;

                        //find the closest point to current fix
                        for (int t = 0; t < ptCount; t++)
                        {
                            minDistMap = 100000000;
                            double distMap = ((h - ct.ptList[t].easting) * (h - ct.ptList[t].easting))
                                            + ((i - ct.ptList[t].northing) * (i - ct.ptList[t].northing));
                            if (distMap < minDistMap)
                            {
                                minDistMap = distMap;
                                closestPointMap = t;
                            }
                        }

                        if (minDistMap < 25)
                        {

                            mapListPt point = new mapListPt(h, i, ct.ptList[closestPointMap].altitude, ct.ptList[closestPointMap].cutAltitude, ct.ptList[closestPointMap].lastPassAltitude);
                            ct.mapList.Add(point);

                        }

                        int closestPointMap2 = 0;
                        int ptCount2 = ct.ptList.Count - 1;

                        //find the closest point to current fix
                        for (int t = 0; t < ptCount2; t++)
                        {
                            minDistMap2 = 100000000;
                            double distMap2 = (((h + 1) - ct.ptList[t].easting) * ((h + 1) - ct.ptList[t].easting))
                                            + ((i - ct.ptList[t].northing) * (i - ct.ptList[t].northing));
                            if (distMap2 < minDistMap2) { minDistMap2 = distMap2; closestPointMap2 = t; }
                        }

                        if (minDistMap2 < 25)
                        {

                            mapListPt point2 = new mapListPt((h + 1), i, ct.ptList[closestPointMap2].altitude, ct.ptList[closestPointMap2].cutAltitude, ct.ptList[closestPointMap2].lastPassAltitude);
                            ct.mapList.Add(point2);

                        }
                    }
                }
            }
            FileSaveMapPt();

        }

then in CContour I modified DrawContourLine line 401
It draw with OpenGL.GL_QUAD_STRIP


 //dot test by Pat
            lastMapValue = -9999999;
            sndLastMapValue = -9999999;

            for (int h = 0; h < ptCount; h++)
            {

                if (mapList[h].altitudeMap < 100) gl.Color(0.5f, 0.900f, 0.90f);
                else gl.Color(0.98f, 0.2f, 0.0f);  
                
                if (mapList[h].northingMap < lastMapValue )
                {
                    gl.End();
                    gl.Begin(OpenGL.GL_QUAD_STRIP);
                    gl.Vertex(mapList[h].eastingMap, mapList[h].northingMap, 0);
                }
                else gl.Vertex(mapList[h].eastingMap, mapList[h].northingMap, 0);

                sndLastMapValue = lastMapValue;
                lastMapValue = mapList[h].northingMap;
            }
            gl.End();

If someone can take a look and make it work for the closestPoint thing it would be appreciated.

Code here:https://github.com/Pat-I/OpenGrade3D

Edit: I have modified the code, now with GL_QUADS and much less points. I still must find out why that closestpoint don’t work , after we will be able to colour it according the cut fill value.
Edit2: Bug Found, see post below.

1 Like

I worked this out last week, sort of. I do not have access to it over the weekend, I’ll post next week. I took the whole field and found an average. This gets mapped by color. As the elevation gets higher away from average it decreases the green, lower it decreases the red. The value is mapped 0 to 256 between average and max, opposite for less. The cut was mapped separately. Determine the max cut, then set the current color to the mapped value, green drops out accordingly. Fill, is done just the opposite but red is dropped out. You toggle between all three.

Now the look ahead is done similar to what you have done above. I stepped along a heading line and created a new list of points only containing the closest point to that step. Then this set of points was fed into the bottom screen. A line is drawn across the field point to point. In the general direction you are driving.

Concerning your code above, I fought with a single i in a loop that needed an h, but the outer loop used the i. So it always set to the last value. I looked for this above, but did not catch one. It took me a while to fine my error, good luck.

Again, I’ll post my code next week. By the way, I did get the blade looking for and mapping to the point in the bottom screen.

2 Likes

Re looked at your code. During the double for loop h then i, you are collecting two points eash time, First a point that is closest to h (one step), then you are collecting a point that is forward one step in the h direction, h+1, then the next time around you are going to be in the same location h (which is now h+1). That’s two points in the exact same location. Point two is redundant. Comment that out and ask it to Console.WriteLine(closestMapPoint); This should give you a list of groups of numbers.
My thinking if the surgey points are 5 meters apart, and you are breaking it to a 1x1 grid, you will have a couple of data points that have the same closest survey point. Something like:
8
8
8
7
7
7
4
4
4
Etc.
Worth a try. Undo would fix it.

There is a problem in the drawing for. You do not start drawing but you end . Something is not right. Probe may be in this, not so much in the collection.

1 Like

I found my error, the minDistMap = 10000000 has to be outside the loop!
now it look like this:
opengrade3D

Next step will be adding more colour. @KentStuff thanks for the explanations.

I also want to use the lastpass value to record every time the blade pass below the lastpass and the land height. For the visual progress and the max cut depth.
I think we cannot record the filling zones since we don’t know when the blade is empty.

Edit I uploaded to github three times today so the code changed a lot. first it was drawing squares by add two points thus the doubles points. now it draw a square by the center. search for drawPtWidth for the pixel dimension and minDistMapDist for the distance from point to draw.

2 Likes

Good catch. I did that a time or two as well.

I was thinking that all cuts modify the survey by the height of the blade. The fill could only be recorded by a separate gps on a trailing roller at best. Or some sort of Lidar mount behind the blade.

The color mapping took some thinking. Setting all colors full (white ) at the survey average, or the base, then lower one the further away was my best so far. But, I had to sit down with pen and paper to get the mapping right.

2 Likes

Did some testing with the HW setup, and modified the .ino for 10-bit PWM (actually this was more for the autosteer but didn’t have the hardware at hand so tested on this).

Seems to be working quite well, now there’s 1024 steps in the PWM control. Maybe that’s of use here as well especially with high flow valves. I’ll incorporate that into the latest ino code from Pat later when I got time.

2 Likes

Now I made my map colouring with the cut fill value. Black when no value, white when o, red when fill, green when cut
foropengrade3D

with @nut 's map:
opengrade3D_2

Maybe it will be better to have a scale with 5 or 7 distinct colours?

1 Like

Working on some changes. The survey points are now just points. Widened the screen view and changed the simulator grade control to only set the blade down or up (in centimeters). The elevation is controlled by the elevation of the closest ground survey. The profile in the picture in the bottom is straight in front of you and within the closest survey points. Not sure you can tell from the main screen but the elevations are actually drawn at elevation. This view is looking down the hill. I’ll try to figure out how to get the settings and such back on the side, maybe in a fly out. But just making small steps. I worked on actually cutting the survey points as you cross them, if the blade was less than the point. Had something backward and it grew instead of cut.

image

This is it looking toward the hill on the left. As you can see the fine red line from point to point is the closest points in a straight line looking ahead. This is also just the greens and reds, sort of. The blues get washed out the further away from average as well.

image

The code looks something like this:

 for (int i = 1; i < ptCount; i++)
                    {
                    if (ptList[i].altitude != -1)
                    {
                        float green = Convert.ToSingle(256 / 256);
                        float red = Convert.ToSingle(256 / 256);
                        float blue = Convert.ToSingle(256 / 256);
                        sinSectionHeading = Math.Sin(-ptList[i].heading);
                        cosSectionHeading = Math.Cos(-ptList[i].heading);
                        if (avg <= ptList[i].altitude)
                        {
                            green = Convert.ToSingle(1-((ptList[i].altitude- avg) / (max-avg)));
                            blue = Convert.ToSingle(1 - ((ptList[i].altitude - avg) / (max - avg)));
                            }
                        if (ptList[i].altitude < avg)
                        {
                            red = Convert.ToSingle(1 - ((avg- ptList[i].altitude) / (avg - min)));
                            blue = Convert.ToSingle(1 - ((avg - ptList[i].altitude) / (avg - min)));
                        }

                        gl.Color(red, green, blue);
                        gl.Begin(OpenGL.GL_LINES);
                        gl.Vertex((cosSectionHeading * -toole / 2) + ptList[i].easting,
                           (sinSectionHeading * -toole / 2) + ptList[i].northing, ptList[i].altitude-avg);
                        gl.Vertex((cosSectionHeading * toole / 2) + ptList[i].easting,
                           (sinSectionHeading * toole / 2) + ptList[i].northing, ptList[i].altitude-avg);
                            gl.Vertex((sinSectionHeading * -toole / 2) + ptList[i].easting,
                           (cosSectionHeading * -toole / 2) + ptList[i].northing, ptList[i].altitude - avg);
                            gl.Vertex((sinSectionHeading * toole / 2) + ptList[i].easting,
                               (cosSectionHeading * toole / 2) + ptList[i].northing, ptList[i].altitude - avg);

                            gl.End();
                    }

Probably a thousand better other ways to to do this but this is what I came up with. No laughing at the coding.

1 Like

I now have a version of opengrade (for autonomous survey not the 3d) with a lot of the features requested.
opengrade
It have the relay port, the valve setting tab, the laser mode, adjustable distance view under and above the ground, adjustable distance from the survey line for the automatic blade height, on the under right tab the distance from the ground, and some others minors changes.

I have now a release with an installer for a clean install. (OpenGradeSetup.msi)

I will work with it in the next weeks to see if there are bugs or issues.
If you try it and have comments or issues you can post here or pm me.

4 Likes

Hey @KentStuff could you try putting triple back ticks on a separate line before and after the code? I think it will make it more readable and copy able.

Or copy these ``` they are sometimes hard to find on phones. On Windows it is the top left hand key on the keyboard.

3 Likes

That is far better. What does that do? Just keep the formatting? And does that work in other programs? Just never seen it before.

1 Like

Just a trick I learnt over here Blynk

1 Like

Easier to view. Makes the post smaller. If you dnt format like this and the next person copies it into Arduino IDE it causes funny errors. But I dnt know how other programs work.

1 Like

How do you guys survey the land? I tried to use an android app called SWMaps with my f9p with correction, but found that the height is rounded to closest 10cm.

1 Like

Been playing with this on desktop. I really like it so far. and havnt had any issues yet. The extra push to zero window and the ability to switch from ref only to laser is good. The laser button showing on and off and turning green is great the old one was hard to see. Have you thought much about making it possable to enlarge the 3 number boxes. In a dozer it would be a big help. Havnt go my on/off valve on dozer yet but hopefully will find time soon.
Great Work