Configurator.Net: Kill old VmBase class, update sensor and Tx views

git-svn-id: https://arducopter.googlecode.com/svn/trunk@1664 f9c3cf11-9bcb-44bc-f272-b75c42450872
This commit is contained in:
mandrolic 2011-02-16 22:19:32 +00:00
parent 72d9f52d3b
commit 3299aa272d
10 changed files with 71 additions and 191 deletions

View File

@ -11,7 +11,7 @@ namespace ArducopterConfigurator.PresentationModels
/// There is a unit test to cover it but it will need fixing. /// There is a unit test to cover it but it will need fixing.
/// TODO: test this /// TODO: test this
/// </remarks> /// </remarks>
public class AltitudeHoldConfigVm : CrudVm, IPresentationModel, ISupportsPropertyPopulation public class AltitudeHoldConfigVm : CrudVm
{ {
public AltitudeHoldConfigVm() public AltitudeHoldConfigVm()
{ {

View File

@ -4,11 +4,9 @@ using System.Diagnostics;
namespace ArducopterConfigurator.PresentationModels namespace ArducopterConfigurator.PresentationModels
{ {
public class CalibrationOffsetsDataVm : VmBase, IPresentationModel public class CalibrationOffsetsDataVm : NotifyProperyChangedBase, IPresentationModel
{ {
public CalibrationOffsetsDataVm() private readonly string[] PropsInUpdateOrder = new[]
{
PropsInUpdateOrder = new[]
{ {
"GyroRollOffset", "GyroRollOffset",
"GyroPitchOffset", "GyroPitchOffset",
@ -18,6 +16,10 @@ namespace ArducopterConfigurator.PresentationModels
"AccelZOffset" "AccelZOffset"
}; };
public CalibrationOffsetsDataVm()
{
RefreshCommand = new DelegateCommand(_ => RefreshValues()); RefreshCommand = new DelegateCommand(_ => RefreshValues());
UpdateCommand = new DelegateCommand(_ => UpdateValues()); UpdateCommand = new DelegateCommand(_ => UpdateValues());
} }
@ -43,7 +45,10 @@ namespace ArducopterConfigurator.PresentationModels
public void UpdateValues() public void UpdateValues()
{ {
if (sendTextToApm != null) if (sendTextToApm != null)
sendTextToApm(this, new sendTextToApmEventArgs(ComposePropsWithCommand("I"))); {
var apmString = PropertyHelper.ComposePropValuesWithCommand(this, PropsInUpdateOrder, "I");
sendTextToApm(this, new sendTextToApmEventArgs(apmString));
}
} }
public string Name public string Name
@ -64,7 +69,10 @@ namespace ArducopterConfigurator.PresentationModels
public void handleLineOfText(string strRx) public void handleLineOfText(string strRx)
{ {
PopulatePropsFromUpdate(strRx, true); PropertyHelper.PopulatePropsFromUpdate(this, PropsInUpdateOrder, strRx, true);
if (updatedByApm != null)
updatedByApm(this, EventArgs.Empty);
} }
public event EventHandler<sendTextToApmEventArgs> sendTextToApm; public event EventHandler<sendTextToApmEventArgs> sendTextToApm;

View File

@ -5,7 +5,7 @@ namespace ArducopterConfigurator.PresentationModels
/// <summary> /// <summary>
/// Common base for the simple VMs that deal with an update from APM and Get and Update them /// Common base for the simple VMs that deal with an update from APM and Get and Update them
/// </summary> /// </summary>
public abstract class CrudVm : NotifyProperyChangedBase, ISupportsPropertyPopulation, ItalksToApm, IPresentationModel public abstract class CrudVm : NotifyProperyChangedBase, IPresentationModel
{ {
protected string updateString; protected string updateString;
protected string refreshString; protected string refreshString;
@ -33,7 +33,7 @@ namespace ArducopterConfigurator.PresentationModels
{ {
if (sendTextToApm != null) if (sendTextToApm != null)
{ {
var apmString = PropertyHelper.ComposePropValuesWithCommand(this, updateString); var apmString = PropertyHelper.ComposePropValuesWithCommand(this, PropsInUpdateOrder, updateString);
sendTextToApm(this, new sendTextToApmEventArgs(apmString)); sendTextToApm(this, new sendTextToApmEventArgs(apmString));
} }
} }
@ -52,7 +52,7 @@ namespace ArducopterConfigurator.PresentationModels
public void handleLineOfText(string strRx) public void handleLineOfText(string strRx)
{ {
PropertyHelper.PopulatePropsFromUpdate(this, strRx, true); PropertyHelper.PopulatePropsFromUpdate(this,PropsInUpdateOrder, strRx, true);
if (updatedByApm != null) if (updatedByApm != null)
updatedByApm(this, EventArgs.Empty); updatedByApm(this, EventArgs.Empty);

View File

@ -25,25 +25,42 @@ namespace ArducopterConfigurator.PresentationModels
/// ///
/// When the VM is deactivated, the model tells the APM to cease sending the realtime updates /// When the VM is deactivated, the model tells the APM to cease sending the realtime updates
/// </remarks> /// </remarks>
public class SensorsVm : VmBase, IPresentationModel public class SensorsVm : NotifyProperyChangedBase, IPresentationModel
{ {
public string Name public string Name
{ {
get { return "Sensor Data"; } get { return "Sensor Data"; }
} }
private readonly string[] _propsInUpdateOrder = new[]
{
"LoopTime",
"GyroRoll",
"GyroPitch",
"GyroYaw",
"Unused", // Throttle
"Unused", // control roll
"Unused", // control pitch
"Unused", // control yaw
"MotorFront",
"MotorRear",
"MotorRight",
"MotorLeft",
"AccelRoll",
"AccelPitch",
"AccelZ",
};
public void Activate() public void Activate()
{ {
if (sendTextToApm!=null) if (sendTextToApm!=null)
sendTextToApm(this, new sendTextToApmEventArgs("S")); sendTextToApm(this, new sendTextToApmEventArgs("S"));
} }
public void DeActivate() public void DeActivate()
{ {
if (sendTextToApm != null) if (sendTextToApm != null)
sendTextToApm(this, new sendTextToApmEventArgs("X")); sendTextToApm(this, new sendTextToApmEventArgs("X"));
} }
public event EventHandler updatedByApm; public event EventHandler updatedByApm;
@ -51,57 +68,12 @@ namespace ArducopterConfigurator.PresentationModels
public void handleLineOfText(string strRx) public void handleLineOfText(string strRx)
{ {
var strs = strRx.Split(','); PropertyHelper.PopulatePropsFromUpdate(this, _propsInUpdateOrder, strRx, false);
var ints = new List<int>();
foreach (var s in strs)
{
int val;
if (!int.TryParse(s, out val))
{
Debug.WriteLine("(Flight Data) Could not parse expected integer: " + s);
return;
}
ints.Add(val);
}
if (ints.Count!=15)
{
Debug.WriteLine("Flight Data seentence expected, but only got one of size: " + ints.Count);
return;
}
LoopTime = ints[0];
GyroRoll = ints[1];
GyroPitch = ints[2];
GyroYaw = ints[3];
MotorFront = ints[8];
MotorRear = ints[9];
MotorRight = ints[10];
MotorLeft = ints[11];
AccelRoll = ints[12];
AccelPitch = ints[13];
AccelZ = ints[14];
} }
public event EventHandler<sendTextToApmEventArgs> sendTextToApm; public event EventHandler<sendTextToApmEventArgs> sendTextToApm;
// 2,-10,3,-2,1011,1012,1002,1000,1001,1003,1002,1004
// Loop Time = 2
// Roll Gyro Rate = -10
// Pitch Gyro Rate = 3
// Yaw Gyro Rate = -2
// Throttle Output = 1011
// Roll PID Output = 1012
// Pitch PID Output = 1002
// Yaw PID Output 1000
// Front Motor Command = 1001 PWM output sent to right motor (ranges from 1000-2000)
// Rear Motor Command 1003
// Right Motor Command = 1002
// Left Motor Command = 1004
// then adc 4,3, and 5
private int _loopTime; private int _loopTime;
public int LoopTime public int LoopTime
{ {
@ -233,5 +205,7 @@ namespace ArducopterConfigurator.PresentationModels
FirePropertyChanged("AccelZ"); FirePropertyChanged("AccelZ");
} }
} }
public int Unused { get; set; }
} }
} }

View File

@ -4,11 +4,9 @@ using System.Diagnostics;
namespace ArducopterConfigurator.PresentationModels namespace ArducopterConfigurator.PresentationModels
{ {
public class TransmitterChannelsVm : VmBase, IPresentationModel public class TransmitterChannelsVm : NotifyProperyChangedBase, IPresentationModel
{ {
public TransmitterChannelsVm() private readonly string[] _propsInUpdateOrder = new[]
{
PropsInUpdateOrder = new[]
{ {
"Roll", // Aileron "Roll", // Aileron
"Pitch", // Elevator "Pitch", // Elevator
@ -21,6 +19,9 @@ namespace ArducopterConfigurator.PresentationModels
"YawMidValue", "YawMidValue",
}; };
public TransmitterChannelsVm()
{
ResetCommand = new DelegateCommand(_ => ResetWatermarks()); ResetCommand = new DelegateCommand(_ => ResetWatermarks());
} }
@ -34,7 +35,6 @@ namespace ArducopterConfigurator.PresentationModels
ModeMax = ModeMin = Mode; ModeMax = ModeMin = Mode;
} }
public ICommand ResetCommand { get; private set; } public ICommand ResetCommand { get; private set; }
public int RollMidValue { get; set; } public int RollMidValue { get; set; }
@ -204,9 +204,6 @@ namespace ArducopterConfigurator.PresentationModels
} }
} }
private int _mode; private int _mode;
public int Mode public int Mode
{ {
@ -310,7 +307,8 @@ namespace ArducopterConfigurator.PresentationModels
public void handleLineOfText(string strRx) public void handleLineOfText(string strRx)
{ {
PopulatePropsFromUpdate(strRx, false); PropertyHelper.PopulatePropsFromUpdate(this, _propsInUpdateOrder, strRx, false);
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
namespace ArducopterConfigurator namespace ArducopterConfigurator
{ {
@ -9,11 +10,6 @@ namespace ArducopterConfigurator
} }
public interface ISupportsPropertyPopulation : ISupportsExternalInvokedInpc
{
string [] PropsInUpdateOrder { get;}
}
/// <summary> /// <summary>
/// Helper class that takes an update from the APM and writes to properties of an object using reflection /// Helper class that takes an update from the APM and writes to properties of an object using reflection
/// </summary> /// </summary>
@ -31,18 +27,17 @@ namespace ArducopterConfigurator
// Common method for creating the update data // Common method for creating the update data
// sentence sent to APM is the commandChar followed by the property // sentence sent to APM is the commandChar followed by the property
// vals in the correct order, seperated by semicolons // vals in the correct order, seperated by semicolons
public static string ComposePropValuesWithCommand(ISupportsPropertyPopulation obj, string commandChar) public static string ComposePropValuesWithCommand(object obj, IList<string> propertiesToUpdate, string commandChar)
{ {
var strings = new string[obj.PropsInUpdateOrder.Length]; var strings = new string[propertiesToUpdate.Count];
for (int i = 0; i < obj.PropsInUpdateOrder.Length; i++) for (int i = 0; i < propertiesToUpdate.Count; i++)
{ {
var prop = obj.GetType().GetProperty(obj.PropsInUpdateOrder[i]); var prop = obj.GetType().GetProperty(propertiesToUpdate[i]);
if (prop.PropertyType == typeof(bool)) if (prop.PropertyType == typeof(bool))
strings[i] = ((bool)prop.GetValue(obj, null)) ? "1" : "0"; strings[i] = ((bool)prop.GetValue(obj, null)) ? "1" : "0";
else else
strings[i] = prop.GetValue(obj, null).ToString(); strings[i] = prop.GetValue(obj, null).ToString();
} }
return commandChar + string.Join(";", strings); return commandChar + string.Join(";", strings);
@ -50,27 +45,27 @@ namespace ArducopterConfigurator
// Common method for populating properties, using a hardcoded // Common method for populating properties, using a hardcoded
// property update order, and reflection to get the property type // property update order, and reflection to get the property type
public static void PopulatePropsFromUpdate(ISupportsPropertyPopulation obj,string strRx, bool fireInpc) public static void PopulatePropsFromUpdate(ISupportsExternalInvokedInpc obj,IList<string> propertiesToUpdate, string strRx, bool fireInpc)
{ {
var strs = strRx.Split(','); var strs = strRx.Split(',');
if (obj.PropsInUpdateOrder.Length != strs.Length) if (propertiesToUpdate.Count != strs.Length)
{ {
Console.WriteLine("Processing update with " + strs.Length Console.WriteLine("Processing update with " + strs.Length
+ " values, but have " + obj.PropsInUpdateOrder.Length + " values, but have " + propertiesToUpdate.Count
+ " properties to populate. Ignoring this update"); + " properties to populate. Ignoring this update");
return; return;
} }
for (int i = 0; i < obj.PropsInUpdateOrder.Length; i++) for (int i = 0; i < propertiesToUpdate.Count; i++)
{ {
var prop = obj.GetType().GetProperty(obj.PropsInUpdateOrder[i]); var prop = obj.GetType().GetProperty(propertiesToUpdate[i]);
var s = strs[i]; var s = strs[i];
object value = null; object value = null;
if (prop == null) if (prop == null)
{ {
Console.WriteLine("Trying to set non existant property: " + obj.PropsInUpdateOrder[i]); Console.WriteLine("Trying to set non existant property: " + propertiesToUpdate[i]);
break; break;
} }
@ -79,7 +74,7 @@ namespace ArducopterConfigurator
float val; float val;
if (!float.TryParse(s, out val)) if (!float.TryParse(s, out val))
{ {
Console.WriteLine("Error parsing float: {0}, VM: {1}" + s, "TODO"); Console.WriteLine("Error parsing float: {0}, VM: {1}" + s, obj);
break; break;
} }
value = val; value = val;
@ -89,7 +84,7 @@ namespace ArducopterConfigurator
float val; float val;
if (!float.TryParse(s, out val)) if (!float.TryParse(s, out val))
{ {
Console.WriteLine("Error parsing float (bool): {0}, VM: {1}" + s, "TODO"); Console.WriteLine("Error parsing float (bool): {0}, VM: {1}" + s, obj);
break; break;
} }
value = val != 0.0; value = val != 0.0;
@ -100,7 +95,7 @@ namespace ArducopterConfigurator
int val; int val;
if (!int.TryParse(s, out val)) if (!int.TryParse(s, out val))
{ {
Console.WriteLine("Error parsing int:{0}, VM: {1}" + s, "TODO"); Console.WriteLine("Error parsing int:{0}, VM: {1}" + s, obj);
break; break;
} }
value = val; value = val;
@ -109,102 +104,7 @@ namespace ArducopterConfigurator
prop.SetValue(obj, value, null); prop.SetValue(obj, value, null);
if (fireInpc) if (fireInpc)
obj.FirePropertyChanged(obj.PropsInUpdateOrder[i]); obj.FirePropertyChanged(propertiesToUpdate[i]);
}
}
}
public abstract class VmBase : NotifyProperyChangedBase
{
protected string[] PropsInUpdateOrder;
// Common method for creating the update data
// sentence sent to APM is the commandChar followed by the property
// vals in the correct order, seperated by semicolons
protected string ComposePropsWithCommand(string commandChar)
{
var strings = new string[PropsInUpdateOrder.Length];
for (int i = 0; i < PropsInUpdateOrder.Length; i++)
{
var prop = this.GetType().GetProperty(PropsInUpdateOrder[i]);
if (prop.PropertyType == typeof(bool))
strings[i] = ((bool)prop.GetValue(this, null)) ? "1" : "0";
else
strings[i] = prop.GetValue(this, null).ToString();
}
return commandChar + string.Join(";", strings);
}
// 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)
{
var strs = strRx.Split(',');
if (PropsInUpdateOrder.Length != strs.Length)
{
Console.WriteLine("Processing update with " + strs.Length
+ " values, but have " + PropsInUpdateOrder.Length
+ " properties to populate. Ignoring this update");
return;
}
for (int i = 0; i < PropsInUpdateOrder.Length; i++)
{
var prop = this.GetType().GetProperty(PropsInUpdateOrder[i]);
var s = strs[i];
object value = null;
if (prop == null)
{
Console.WriteLine("Trying to set non existant property: " + PropsInUpdateOrder[i]);
break;
}
if (prop.PropertyType == typeof(float))
{
float val;
if (!float.TryParse(s, out val))
{
Console.WriteLine("Error parsing float: {0}, VM: {1}" + s, "TODO");
break;
}
value = val;
}
if (prop.PropertyType == typeof(bool))
{
float val;
if (!float.TryParse(s, out val))
{
Console.WriteLine("Error parsing float (bool): {0}, VM: {1}" + s, "TODO");
break;
}
value = val != 0.0;
}
if (prop.PropertyType == typeof(int))
{
int val;
if (!int.TryParse(s, out val))
{
Console.WriteLine("Error parsing int:{0}, VM: {1}" + s, "TODO");
break;
}
value = val;
}
prop.SetValue(this, value, null);
if (fireInpc)
FirePropertyChanged(PropsInUpdateOrder[i]);
} }
} }

View File

@ -21,8 +21,8 @@ namespace ArducopterConfigurator
var t = Type.GetType("Mono.Runtime"); var t = Type.GetType("Mono.Runtime");
IsMonoRuntime = (t != null); IsMonoRuntime = (t != null);
//var session = new CommsSession(); var session = new CommsSession();
var session = new FakeCommsSession(); //var session = new FakeCommsSession();
var mainVm = new MainVm(session); var mainVm = new MainVm(session);

View File

@ -110,7 +110,7 @@
// //
// FlightDataVmBindingSource // FlightDataVmBindingSource
// //
this.FlightDataVmBindingSource.DataSource = typeof(ArducopterConfigurator.PresentationModels.FlightDataVm); this.FlightDataVmBindingSource.DataSource = typeof(ArducopterConfigurator.PresentationModels.SensorsVm);
// //
// label5 // label5
// //

View File

@ -17,7 +17,7 @@ namespace ArducopterConfigurator.views
InitializeComponent(); InitializeComponent();
} }
public override void SetDataContext(FlightDataVm vm) public override void SetDataContext(SensorsVm vm)
{ {
FlightDataVmBindingSource.DataSource = vm; FlightDataVmBindingSource.DataSource = vm;
@ -26,5 +26,5 @@ namespace ArducopterConfigurator.views
} }
} }
// Required for VS2008 designer. No functional value // Required for VS2008 designer. No functional value
public class FlightDataViewDesignable : ViewCommon<FlightDataVm> { } public class FlightDataViewDesignable : ViewCommon<SensorsVm> { }
} }

View File

@ -22,7 +22,7 @@ namespace ArducopterConfigurator
// IPresentationModel to IView map // IPresentationModel to IView map
private readonly Dictionary<Type, Type> _viewMap = new Dictionary<Type, Type> private readonly Dictionary<Type, Type> _viewMap = new Dictionary<Type, Type>
{ {
{typeof (FlightDataVm), typeof (FlightDataView)}, {typeof (SensorsVm), typeof (FlightDataView)},
{typeof (TransmitterChannelsVm), typeof (TransmitterChannelsView)}, {typeof (TransmitterChannelsVm), typeof (TransmitterChannelsView)},
{typeof (CalibrationOffsetsDataVm), typeof (CalibrationView)}, {typeof (CalibrationOffsetsDataVm), typeof (CalibrationView)},
{typeof (MotorCommandsVm), typeof (MotorCommandsView)}, {typeof (MotorCommandsVm), typeof (MotorCommandsView)},