2011-01-26 17:17:44 -04:00
|
|
|
using System;
|
2010-12-18 18:23:09 -04:00
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
namespace ArducopterConfigurator
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Monitor VM base class
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// Common base for some factored out things like only passing data to an active
|
|
|
|
/// Monitor, etc
|
|
|
|
/// </remarks>
|
|
|
|
public abstract class MonitorVm : NotifyProperyChangedBase, IPresentationModel
|
|
|
|
{
|
2011-02-04 17:45:31 -04:00
|
|
|
private readonly IComms _sp;
|
2010-12-18 18:23:09 -04:00
|
|
|
protected bool isActive;
|
|
|
|
protected string[] PropsInUpdateOrder;
|
|
|
|
|
2010-12-20 18:14:39 -04:00
|
|
|
protected MonitorVm(IComms sp)
|
2010-12-18 18:23:09 -04:00
|
|
|
{
|
|
|
|
_sp = sp;
|
|
|
|
_sp.LineOfDataReceived += sp_LineOfDataReceived;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sp_LineOfDataReceived(string obj)
|
|
|
|
{
|
|
|
|
if (isActive)
|
|
|
|
OnStringReceived(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when the mode is selected
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// Any initialising commands should be sent to the serial port
|
|
|
|
/// when this method is called.
|
|
|
|
/// </remarks>
|
|
|
|
public void Activate()
|
|
|
|
{
|
|
|
|
isActive = true;
|
|
|
|
OnActivated();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void DeActivate()
|
|
|
|
{
|
|
|
|
isActive = false;
|
|
|
|
OnDeactivated();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void OnDeactivated()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void OnActivated()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Send raw text to the Arducopter
|
|
|
|
/// </summary>
|
|
|
|
protected void SendString(string strToSend)
|
|
|
|
{
|
2010-12-23 11:59:00 -04:00
|
|
|
if (_sp.IsConnected)
|
2010-12-18 18:23:09 -04:00
|
|
|
_sp.Send(strToSend);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Call-back for text sent back from the Arducopter
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// This is called when a full line of text is received from the APM
|
|
|
|
/// This will not be called when the mode is not selected
|
|
|
|
/// </remarks>
|
|
|
|
protected abstract void OnStringReceived(string strReceived);
|
|
|
|
|
|
|
|
#region Implementation of IPresentationModel
|
|
|
|
|
|
|
|
public abstract string Name { get; }
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
// Common method for populating properties, using a hardcoded
|
|
|
|
// property update order, and reflection to get the property type
|
|
|
|
protected void PopulatePropsFromUpdate(string strRx, bool fireInpc)
|
|
|
|
{
|
2011-01-26 17:17:44 -04:00
|
|
|
|
2010-12-18 18:23:09 -04:00
|
|
|
var strs = strRx.Split(',');
|
|
|
|
|
|
|
|
if (PropsInUpdateOrder.Length!=strs.Length)
|
|
|
|
{
|
2011-02-04 17:45:31 -04:00
|
|
|
Console.WriteLine("Processing update with " + strs.Length
|
2010-12-18 18:23:09 -04:00
|
|
|
+ " values, but have " + PropsInUpdateOrder.Length
|
|
|
|
+ " properties to populate. Ignoring this update");
|
|
|
|
return;
|
|
|
|
}
|
2011-02-04 17:45:31 -04:00
|
|
|
|
2010-12-18 18:23:09 -04:00
|
|
|
for (int i = 0; i < PropsInUpdateOrder.Length; i++)
|
|
|
|
{
|
|
|
|
var prop = this.GetType().GetProperty(PropsInUpdateOrder[i]);
|
|
|
|
var s = strs[i];
|
|
|
|
object value = null;
|
|
|
|
|
2011-02-04 17:45:31 -04:00
|
|
|
if (prop == null)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Trying to set non existant property: " + PropsInUpdateOrder[i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-12-18 18:23:09 -04:00
|
|
|
if (prop.PropertyType == typeof(float))
|
|
|
|
{
|
|
|
|
float val;
|
|
|
|
if (!float.TryParse(s, out val))
|
|
|
|
{
|
2011-01-27 11:58:32 -04:00
|
|
|
Console.WriteLine("Error parsing float: {0}, VM: {1}" + s, Name);
|
2010-12-18 18:23:09 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
value = val;
|
|
|
|
}
|
|
|
|
if (prop.PropertyType == typeof(bool))
|
|
|
|
{
|
|
|
|
float val;
|
|
|
|
if (!float.TryParse(s, out val))
|
|
|
|
{
|
2011-01-27 11:58:32 -04:00
|
|
|
Console.WriteLine("Error parsing float (bool): {0}, VM: {1}" + s, Name);
|
2010-12-18 18:23:09 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
value = val != 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prop.PropertyType == typeof(int))
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
if (!int.TryParse(s, out val))
|
|
|
|
{
|
2011-01-27 11:58:32 -04:00
|
|
|
Console.WriteLine("Error parsing int:{0}, VM: {1}" + s, Name);
|
2010-12-18 18:23:09 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
value = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
prop.SetValue(this, value, null);
|
|
|
|
|
|
|
|
if (fireInpc)
|
|
|
|
FirePropertyChanged(PropsInUpdateOrder[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Common method for sending/updating data
|
|
|
|
// sentence sent to APM is the commandChar followed by the property
|
|
|
|
// vals in the correct order, seperated by semicolons
|
|
|
|
protected void SendPropsWithCommand(string commandChar)
|
|
|
|
{
|
|
|
|
var strings = new string[PropsInUpdateOrder.Length];
|
|
|
|
for (int i = 0; i < PropsInUpdateOrder.Length; i++)
|
|
|
|
{
|
|
|
|
var prop = this.GetType().GetProperty(PropsInUpdateOrder[i]);
|
2010-12-22 18:30:17 -04:00
|
|
|
|
|
|
|
if (prop.PropertyType == typeof(bool))
|
|
|
|
strings[i] = ((bool) prop.GetValue(this, null)) ? "1" : "0";
|
|
|
|
else
|
|
|
|
strings[i] = prop.GetValue(this, null).ToString();
|
2010-12-18 18:23:09 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var sentence = commandChar + string.Join(";", strings);
|
|
|
|
SendString(sentence);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|