Rover Mowing Success

Ok that version leaves a lot to be desired. Here’s a better one where you can nudge the waypoints around visually with arrow buttons. I defaulted the nudge value to 0.5 meter since my mower is about 1 meter wide :slight_smile:

I’m working on a version where you can just nudge selected areas. Unfortunately FlightPlanner.cs has some protected variables making it difficult.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MissionPlanner.Utilities;
using MissionPlanner.Controls;
using System.IO;
using System.Windows.Forms;
using System.Diagnostics;
using MissionPlanner;
using System.Drawing;
// Mission Planner Nudge plugin. Work in progress.
// adds a Nudge right click option in the planner.
// Use at your own risk. 
namespace Shortcuts
{
    public class Plugin : MissionPlanner.Plugin.Plugin
    {
        System.Windows.Forms.TextBox edInput;
        ToolStripMenuItem but;
        MissionPlanner.Controls.MyDataGridView commands;
        public override string Name
        {
            get { return "Waypoint Nudge Plugin"; }
        }

        public override string Version
        {
            get { return "0.10"; }
        }

        public override string Author
        {
            get { return "John Harlow"; }
        }

        public override bool Init()
        {
            return true;
        }

        public override bool Loaded()
        {
            but = new ToolStripMenuItem("Nudge");
            but.Click += but_Click;
            ToolStripItemCollection col = Host.FPMenuMap.Items;
            col.Insert(0, but);
            commands = Host.MainForm.FlightPlanner.Controls.Find("Commands", true).FirstOrDefault() as MissionPlanner.Controls.MyDataGridView;
            return true;
        }

        public override bool Loop()
        {
            return true;
        }

        public override bool Exit()
        {
            return true;
        }

        void but_Click(object sender, EventArgs e)
        {
            Form form;
            form = new Form();
            form.AutoScaleMode = AutoScaleMode.Font;
            SizeF dialogUnits;
            dialogUnits = form.AutoScaleDimensions;
            form.FormBorderStyle = FormBorderStyle.FixedDialog;
            form.MinimizeBox = false;
            form.MaximizeBox = false;
            form.Text = "Waypoint Nudger";
            form.ClientSize = new Size(180, 170);
            form.StartPosition = FormStartPosition.CenterScreen;
            System.Windows.Forms.Label lblPrompt;
            lblPrompt = new System.Windows.Forms.Label();
            lblPrompt.Parent = form;
            lblPrompt.AutoSize = true;
            lblPrompt.Left = 10;
            lblPrompt.Top = 20;
            lblPrompt.Text = "Nudge Dist (meters)";


            edInput = new System.Windows.Forms.TextBox();
            edInput.Parent = form;
            edInput.Left = lblPrompt.Left + 110;
            edInput.Top = lblPrompt.Top;
            edInput.Width = 30;
            edInput.Text = "0.5";
            edInput.SelectAll();

            Size buttonSize = new Size(50 * (int)dialogUnits.Width / 6, 14 * (int)dialogUnits.Height / 6);
            System.Windows.Forms.Button bbOk = new();
            bbOk.Parent = form;
            bbOk.Text = "Close";
            bbOk.DialogResult = DialogResult.OK;
            form.AcceptButton = bbOk;
            bbOk.Location = new Point(65, 130);
            bbOk.Size = buttonSize;


            Size moveButtonSize = new Size(20 * (int)dialogUnits.Width / 6, 14 * (int)dialogUnits.Height / 6);
            System.Windows.Forms.Button bbLeft = new System.Windows.Forms.Button();
            bbLeft.Parent = form;
            bbLeft.Text = char.ConvertFromUtf32(0x2190);
            bbLeft.Location = new Point(50, 60);
            bbLeft.Size = moveButtonSize;
            bbLeft.Click += moveClick;
            bbLeft.Tag = "L";

            System.Windows.Forms.Button bbRight = new System.Windows.Forms.Button();
            bbRight.Parent = form;
            bbRight.Text = char.ConvertFromUtf32(0x2192);
            bbRight.Location = new Point(110, 60);
            bbRight.Size = moveButtonSize;
            bbRight.Click += moveClick;
            bbRight.Tag = "R";

            System.Windows.Forms.Button bbUp = new System.Windows.Forms.Button();
            bbUp.Parent = form;
            bbUp.Text = char.ConvertFromUtf32(0x2191);
            bbUp.Location = new Point(80, 40);
            bbUp.Size = moveButtonSize;
            bbUp.Click += moveClick;
            bbUp.Tag = "U";

            System.Windows.Forms.Button bbDown = new System.Windows.Forms.Button();
            bbDown.Parent = form;
            bbDown.Text = char.ConvertFromUtf32(0x2193);
            bbDown.Location = new Point(80, 80);
            bbDown.Size = moveButtonSize;
            bbDown.Click += moveClick;
            bbDown.Tag = "D";
            form.ShowDialog();
        }

        void moveClick(object sender, EventArgs e)
        {

            double lat_trans = 0;
            double lon_trans = 0;
            double transVal = Double.Parse(edInput.Text);
            switch (((System.Windows.Forms.Button)sender).Tag)
            {
                case "L":
                    lon_trans = -transVal;
                    break;
                case "R":
                    lon_trans = transVal;
                    break;
                case "D":
                    lat_trans = -transVal;
                    break;
                case "U":
                    lat_trans = transVal;
                    break;

            }

            double earth_radius = 6378.137;
            double m_lat = (1 / ((2 * Math.PI / 360) * earth_radius)) / 1000;
            double m_long = (1 / ((2 * Math.PI / 360) * earth_radius)) / 1000; // # 1 meter in degree

            // iterate through the waypoints
            foreach (DataGridViewRow row in commands.Rows)
            {
                if (row.Cells[0].Value.ToString() == MAVLink.MAV_CMD.WAYPOINT.ToString())
                {
                    double lat = Double.Parse(row.Cells[5].Value.ToString());
                    double lon = Double.Parse(row.Cells[6].Value.ToString());
                    // Calculate top, which is lat_translation_meters above
                    double lat_new = lat + (lat_trans * m_lat);
                    // Calculate right, which is long_translation_meters right
                    double lon_new = lon + (lon_trans * m_long) / Math.Cos(lat * (Math.PI / 180));
                    row.Cells[5].Value = lat_new.ToString();
                    row.Cells[6].Value = lon_new.ToString();
                }
            }

            // redraw the map
            Host.MainForm.FlightPlanner.writeKML();
        }
    }
}

@johnharlow You are spot on there John. Because of the great GPS accuracy I am getting small trenches forming.
To be able to offset the waypoints by say 250mm would be very useful. Alternatively I would like to use a different survey grid rather than the spiral one but the towing setup is not really very good for pivot turns.
I am going to now turn the mower itself into a Rover rather than towing it. I will be posting the story from the beginning. At least being able to pivot turn a backwards and forwards mission can be easily changed with the angle option. This will stop the trenches forming over time.

1 Like

If you install my plugin you can offset the waypoints exactly 250mm in any direction with a single click.

Good luck with converting the mower. I have done 2 in the past couple months myself. It is super fun watching them go.

Couple things I did which I feel are must haves:

Use relay module to control ignition and PTO clutch
Switch on RC remote to control ignition - setup radio failsafe to turn ignition off in case of lost comms
Use the 3 position switch on RC remote to control mode: Manual, Hold, Auto
Siyi HM30 with 4k color camera so I can watch as if sitting I’m on the mower - VLC stream viewer on separate monitor
servo control of throttle - use knob on RC controller to adjust
Enclose electronics in waterproof enclosure with filtered fan cooling

2 Likes

Gotta ask- How is the range with that VTX setup? Where do you monitor the video from, indoors?

I have been working on a bot with video feed, and went the 4G route mainly because I was struggling to get useable range.

And also ask— My VRA/VRB knobs do not show in MP, what do yours show up as on the servo setup/ radio calibrate screen?

I’m on 1500 feet of property. Never an issue with range for the HM30. I’m sure its way more than needed but I really wanted the video feed. Yes I sit indoors in the AC while the mower runs out in the Florida heat and dust.

The VRx knobs probably need to be mapped to servo channels in your remote. Which remote do you have? I have a very cheap basic FlySky which works amazingly well. I also have a radiomaster AT10 which for this application is frankly overkill. The $50 flysky does all I need.

Sounds like I probably have the same radio, a Flysky i6X 10channel.

I only need 900-1000’ of range, but, like you, sitting indoors. I bought quite a few wifi card setups on recommendations from others, but eventually cut my losses and went 4G. I’d like to go back to wifi if I was certain the devices I bought would perform.

Now that my platform is mostly working, I may revisit the other options and see what I can get to work.

Sounds good. The HM30 has been flawless in terms of mavlink for me. The video will get choppy at the extremes but I think I can resolve that with a better antenna (the transmitter is just sitting on my desk).

The flysky has rx/tx power indicators and will start to whine if the signal gets low. It too never drops out for me.

Thanks @johnharlow for that. I did see your plugin earlier but unfortunately I have no idea how to install it!
Can you give me some pointers or is there some documentation on installing plugins?
The mower I am going to convert is a towable version meant for quad bikes and ATV’s. I do not have a clutch so need not worry about that.
I will look at disabling the ignition though when radio failsafes.
Throttle will all be done through the speed controllers. I am adding electric motors to the two wheels.
Here is the starting point!

I’m using the DJI V1 goggles and a Vista air unit for video feed. Unfortunately the V1 goggles do not have an HDMI output…V2 does.
Range is 500 meters easily. I get 4 kilometers on my long range drone no problem. Latency is negligable wheras the 4G network I would imagine is much slower.

It is extremely simple. Just open notepad or any other text editor, copy in the source code I posted and save it in the C:\Program Files (x86)\Mission Planner\plugins folder as “nudge.cs”

Then restart mission planner. The new menu item should appear in the right click menu.

3 Likes

Thanks for that. All installed and working perfectly. That is definitely going to help reduce the ruts.
I so wish I understood software and programming!

1 Like

I’m not having any luck getting my aux channel switches to work on this Flysky.- other that channel 9 as the SWC 3 position switch, I’ve been able to get it to work (only as a 2 pos though)

Only my gimbals show green bars in the radio calibrate screen, none of the button channels. They show on servo output page, but I can only get the one switch to work. :thinking:

Whats your setup look like?

Functions → Aux channels:

channel 5 VrA
channel 6 VrB
channel 7 SwA
channel 8 SwB
channel 9 SwC
channel 10 SwD

Hmm- thanks,

In the flysky menu- that’s what I have as well.

What setup in mission planner- servo setup for those channels?

Some of the channels will probably have to be set to RC Pass through, so the signal will pass through the FC and put the signal out on the servo rail.

Thanks, I did try RC passthrough. I can get the switches in question to show in MP on the joystick setup page- in the buttons list- but not on the RC controller calibrate/servo setup page.

(And my apologies for hijacking this thread :confused: )

I did a quick search and I found the following:

It’s most likely transmitter channel mapping.

Start a new topic at this point.