ardupilot/Tools/ArdupilotMegaPlanner/Presenter/ConfigCameraStabPresenter.cs
Michael Oborne 944488afaf APM Planner 1.1.99
Convert to IActivate, IDeactivate scheme, thanks andrew
add support for rfcomm* interfaces on linux
fix guage off screen draw mono issue.
remove use of BackStageViewContentPanel
andrews spacer changes - not using dues to screen space issue
change configpanel constructor to load xml directly
remove IMavlink Interface
fix hsi off screen draw issue on mono
modify hud to use sprite fonts, instead of drawing via GDI+
modify progress reporter to use a 10hz timer to update screen, using invoke/begininvoke fails on mono at 50hz (over 100ms per call).
fix targetalt and target airspeed jumping issue.
lots of cleanup on tab switching, ie stoping timers/other
3dr radio status led update
update ardurover car icon
speedup georef image screen. tested on over 1000 images.
2012-07-22 15:51:05 +08:00

367 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Subjects;
using System.Reflection;
using log4net;
namespace ArdupilotMega.Presenter
{
public class ConfigCameraStabPresenter : INotifyPropertyChanged, IDataErrorInfo
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// These are lightweight PropertyMetaData objects, just so that populating defaults
// and saving etc can be done programatically, rather than explicitely
// This is starting to step on the toes of PropertyDescriptor etc in System.Componentmodel,
// however I wanted to keep 'normal' CLR properties here for testability, and more certain Mono
// compatibility
private readonly List<PropertyMap> _propertyMap = new List<PropertyMap>
{
PropertyMap.Create<int>("CameraPitchMin", "CAM_P_MIN", 1000),
PropertyMap.Create<int>("CameraPitchMax", "CAM_P_MAX", 2000),
PropertyMap.Create<int>("CameraPitchTrim", "CAM_P_TRIM", 1500),
PropertyMap.Create<bool>("CameraPitchReverse", "CAM_P_REV", false),
PropertyMap.Create<float>("CameraPitchGain", "CAM_P_G", 1.0F),
PropertyMap.Create<int>("CameraRollMin", "CAM_R_MIN", 1000),
PropertyMap.Create<int>("CameraRollMax", "CAM_R_MAX", 2000),
PropertyMap.Create<int>("CameraRollTrim", "CAM_R_TRIM", 1500),
PropertyMap.Create<bool>("CameraRollReverse", "CAM_R_REV", false),
PropertyMap.Create<float>("CameraRollGain", "CAM_R_G", 1.0F),
};
private CameraAxisProperties _pitchAxis;
private CameraAxisProperties _rollAxis;
private readonly MAVLink _mavlink;
private readonly Dictionary<string, string> _errors;
public ConfigCameraStabPresenter(MAVLink mavlink)
{
_mavlink = mavlink;
_errors = new Dictionary<string, string>();
RefreshValuesCommand = new DelegateCommand(_ => GetCameraStabVals());
WriteValuesCommand = new DelegateCommand(_ => WriteValues());
SetDefaultsCommand = new DelegateCommand(_ => SetDefaults());
// Todo change to load params once finished
SetDefaults();
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand SetDefaultsCommand { get; private set; }
/// <summary>
/// Try to write the cam stab values to the apm
/// </summary>
public ICommand WriteValuesCommand { get; private set; }
/// <summary>
/// Re-Fetch the cam stab values from teh apm
/// </summary>
public ICommand RefreshValuesCommand { get; private set; }
#region publicBindableProperties
/// <summary>
/// Pitch The lowest PWM
/// </summary>
public int CameraPitchMin
{
get { return _pitchAxis.Min; }
set
{
if (_pitchAxis.Min == value) return;
_pitchAxis.Min = value;
RaisePropertyChanged("CameraPitchMin");
}
}
/// <summary>
/// Pitch The highest PWM
/// </summary>
public int CameraPitchMax
{
get { return _pitchAxis.Max; }
set
{
if (_pitchAxis.Max == value) return;
_pitchAxis.Max = value;
RaisePropertyChanged("CameraPitchMax");
}
}
public int CameraPitchTrim
{
get { return _pitchAxis.Trim; }
set
{
if (_pitchAxis.Trim == value) return;
_pitchAxis.Trim = value;
RaisePropertyChanged("CameraPitchTrim");
}
}
/// <summary>
/// Set higher or lower to scale the travel of the servo
/// </summary>
public float CameraPitchGain
{
get { return _pitchAxis.Gain; }
set
{
if (_pitchAxis.Gain == value) return;
_pitchAxis.Gain = value;
RaisePropertyChanged("CameraPitchGain");
}
}
public bool CameraPitchReverse
{
get { return _pitchAxis.Reverse; }
set
{
if (_pitchAxis.Reverse == value) return;
_pitchAxis.Reverse = value;
RaisePropertyChanged("CameraPitchReverse");
}
}
/// <summary>
/// Roll The lowest PWM
/// </summary>
public int CameraRollMin
{
get { return _rollAxis.Min; }
set
{
if (_rollAxis.Min == value) return;
_rollAxis.Min = value;
RaisePropertyChanged("CameraRollMin");
}
}
/// <summary>
/// Roll The highest PWM
/// </summary>
public int CameraRollMax
{
get { return _rollAxis.Max; }
set
{
if (_rollAxis.Max == value) return;
_rollAxis.Max = value;
RaisePropertyChanged("CameraRollMax");
}
}
public int CameraRollTrim
{
get { return _rollAxis.Trim; }
set
{
if (_rollAxis.Trim == value) return;
_rollAxis.Trim= value;
RaisePropertyChanged("CameraRollTrim");
}
}
/// <summary>
/// Set higher or lower to scale the travel of the servo
/// </summary>
public float CameraRollGain
{
get { return _rollAxis.Gain; }
set
{
if (_rollAxis.Gain == value) return;
_rollAxis.Gain = value;
RaisePropertyChanged("CameraRollGain");
}
}
public bool CameraRollReverse
{
get { return _rollAxis.Reverse; }
set
{
if (_rollAxis.Reverse == value) return;
_rollAxis.Reverse = value;
RaisePropertyChanged("CameraRollReverse");
}
}
private bool hasError;
public bool HasError
{
get { return hasError; }
set
{
if (hasError == value) return;
hasError = value;
RaisePropertyChanged("HasError", false);
}
}
#endregion
private void GetCameraStabVals()
{
foreach (var p in _propertyMap)
{
var pinfo = GetType().GetProperty(p.PresenterPropertyName);
var paramVal = GetParam(p.ApmPropertyName, p.PropertyType);
pinfo.SetValue(this, paramVal, null);
}
}
private void SetDefaults()
{
_propertyMap.ForEach(p => GetType().GetProperty(p.PresenterPropertyName).SetValue(this, p.DefaultValue, null));
}
private void WriteValues()
{
foreach (var p in _propertyMap)
{
var pinfo = GetType().GetProperty(p.PresenterPropertyName);
var val = pinfo.GetValue(this, null);
try
{
// handle boolean
if (val.GetType() == typeof(Boolean))
{
if (!_mavlink.setParam(p.ApmPropertyName, ((Boolean)val) ? 1 : -1))
log.Error("Error setting Camstab parameter");
}
else
{
if (!_mavlink.setParam(p.ApmPropertyName, float.Parse(val.ToString())))
log.Error("Error setting Camstab parameter");
}
}
catch (Exception e)
{
log.Error("Error setting Camstab parameter", e);
}
}
}
private object GetParam(string paramName, Type paramType)
{
if (_mavlink.param.ContainsKey(paramName))
{
return paramType == typeof (bool)
? _mavlink.param[paramName].ToString() == "1"
: Convert.ChangeType(_mavlink.param[paramName].ToString(), paramType);
}
log.ErrorFormat("Could not get param {0}", paramName);
return null;
}
public void Load()
{
RefreshValuesCommand.Execute(null);
}
private void RaisePropertyChanged(string propName, bool shouldValidate = true)
{
if (shouldValidate)
ValidatePropertyValues();
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
private void ValidatePropertyValues()
{
var errCount = _errors.Count;
_errors.Clear();
if (CameraPitchMax < CameraPitchMin)
{
_errors["CameraPitchMax"] = "Max should be > Min";
_errors["CameraPitchMin"] = "Max should be > Min";
}
if ((CameraPitchTrim < CameraPitchMin) || (CameraPitchTrim > CameraPitchMax))
{
_errors["CameraPitchTrim"] = "Trim should be between Min and Max";
}
if (CameraRollMax < CameraRollMin)
{
_errors["CameraRollMax"] = "Max should be > Min";
_errors["CameraRollMin"] = "Max should be > Min";
}
if ((CameraRollTrim < CameraRollMin) || (CameraRollTrim > CameraRollMax))
{
_errors["CameraRollTrim"] = "Trim should be between Min and Max";
}
if (_errors.Count != errCount)
{
this.RaisePropertyChanged("Error", false);
}
HasError = _errors.Count > 0;
}
public string this[string columnName]
{
get { return _errors.ContainsKey(columnName) ? _errors[columnName] : null; }
}
public string Error
{
get { return _errors.Values.FirstOrDefault(); }
}
private struct CameraAxisProperties
{
public int Min;
public int Max;
public int Trim;
public float Gain;
public bool Reverse;
}
private struct PropertyMap
{
public string PresenterPropertyName;
public string ApmPropertyName;
public Type PropertyType;
public object DefaultValue;
public static PropertyMap Create<T>(string presenterPropertyName, string apmPropertyName, object defaultVal)
{
return new PropertyMap
{
PresenterPropertyName = presenterPropertyName,
ApmPropertyName = apmPropertyName,
PropertyType = typeof(T),
DefaultValue = defaultVal
};
}
}
}
}