private static void parseChannel(Tag tag, SmcChannel channel, string name, SmcChannelSettings cs, List <string> warnings) { if (assertChild(tag, name, warnings)) { Tag channelTag = tag.children[name]; parseBool(channelTag, "Invert", ref cs.invert, warnings); if (assertValue(channelTag, "AlternateUse", warnings)) { try { cs.alternateUse = (SmcChannelAlternateUse)Enum.Parse(typeof(SmcChannelAlternateUse), channelTag.values["AlternateUse"]); } catch { warnings.Add("Invalid AlternateUse value \"" + channelTag.values["AlternateUse"] + "\"."); } } if (channel.type() == SmcChannelType.Analog && assertValue(channelTag, "PinMode", warnings)) { try { cs.pinMode = (SmcPinMode)Enum.Parse(typeof(SmcPinMode), channelTag.values["PinMode"]); } catch { warnings.Add("Invalid PinMode value \"" + channelTag.values["PinMode"] + "\"."); } } parseU8(channelTag, "ScalingDegree", ref cs.scalingDegree, warnings); parseRange(channelTag, "Error", ref cs.errorMin, ref cs.errorMax, warnings); parseRange(channelTag, "Input", ref cs.inputMin, ref cs.inputMax, warnings); parseRange(channelTag, "InputNeutral", ref cs.inputNeutralMin, ref cs.inputNeutralMax, warnings); } }
/// <summary> /// Determines what the specified channel is used for (e.g. limit switch or /// controlling the motor speed). /// </summary> /// <param name="channel">Specifies the channel.</param> /// <param name="inputMode">The input mode of the device (Serial/USB, Analog, RC).</param> /// <param name="mixingMode">The mixing mode of the device (None, Left, Right).</param> /// <param name="alternateUse">The alternate use setting for the channel.</param> /// <returns>What the channel is used for.</returns> public static SmcChannelUse use(this SmcChannel channel, SmcInputMode inputMode, SmcMixingMode mixingMode, SmcChannelAlternateUse alternateUse) { if (channel.controlsMotorSpeed(inputMode, mixingMode)) { if (channel == SmcChannel.Analog2 || channel == SmcChannel.Rc2) { return(SmcChannelUse.Steering); } else { return(SmcChannelUse.Throttle); } } else { switch (alternateUse) { default: return(SmcChannelUse.None); case SmcChannelAlternateUse.KillSwitch: return(SmcChannelUse.KillSwitch); case SmcChannelAlternateUse.LimitForward: return(SmcChannelUse.LimitForward); case SmcChannelAlternateUse.LimitReverse: return(SmcChannelUse.LimitReverse); } } }
/// <summary> /// Converts the Raw Value (or Unlimited Raw Value) of a channel in to a user /// friendly string that expresses the value in standard units. /// For example: "1501 us" or "1452 mV". It uses a non-ascii character to /// encode the Greek letter mu in microseconds. /// </summary> public static String rawValueToStandardUnitsString(this SmcChannel channel, UInt16 rawValue) { switch (channel.type()) { case SmcChannelType.RC: return(((rawValue + 2) / 4).ToString() + " \u03BCs"); case SmcChannelType.Analog: return((rawValue * 3300 / 4095).ToString() + " mV"); default: return(rawValue.ToString()); // should not happen } }
/// <summary> /// Returns the default settings for the given channel. /// </summary> /// <param name="channel"></param> /// <returns></returns> public static SmcChannelSettings defaults(SmcChannel channel) { if (channel.type() == SmcChannelType.Analog) { return(SmcChannelSettings.defaultAnalogSettings()); } else { return(SmcChannelSettings.defaultRCSettings()); } }
/// <summary> /// Returns the type of the channel: RC or Analog. /// </summary> public static SmcChannelType type(this SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: case SmcChannel.Analog2: return(SmcChannelType.Analog); case SmcChannel.Rc1: case SmcChannel.Rc2: return(SmcChannelType.RC); default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
private static void WriteElementChannelSettings(this XmlWriter writer, SmcChannel channel, SmcChannelSettings cs) { writer.WriteStartElement(channel.ToString()); writer.WriteElementString("AlternateUse", cs.alternateUse.ToString()); if (channel.type() == SmcChannelType.Analog) { writer.WriteElementString("PinMode", cs.pinMode.ToString()); } writer.WriteElementBool("Invert", cs.invert); writer.WriteElementU32("ScalingDegree", cs.scalingDegree); writer.WriteElementRange("Error", cs.errorMin, cs.errorMax); writer.WriteElementRange("Input", cs.inputMin, cs.inputMax); writer.WriteElementRange("InputNeutral", cs.inputNeutralMin, cs.inputNeutralMax); writer.WriteEndElement(); }
/// <summary> /// Returns true if the specified channel is a limit or kill switch and /// it is currently active. This information comes from the limitStatus /// register. /// </summary> public static bool switchActive(this SmcVariables vars, SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return((vars.limitStatus & SmcLimitStatus.Analog1) != 0); case SmcChannel.Analog2: return((vars.limitStatus & SmcLimitStatus.Analog2) != 0); case SmcChannel.Rc1: return((vars.limitStatus & SmcLimitStatus.Rc1) != 0); case SmcChannel.Rc2: return((vars.limitStatus & SmcLimitStatus.Rc2) != 0); default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Returns a short user friendly name for the channel (e.g. "Analog 1"). /// </summary> public static string shortName(this SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return("Analog 1"); case SmcChannel.Analog2: return("Analog 2"); case SmcChannel.Rc1: return("RC 1"); case SmcChannel.Rc2: return("RC 2"); default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Changes the settings for a specified channel. /// </summary> /// <param name="settings">The settings of the device. This object will be modified.</param> /// <param name="channel">Specifies the channel to change.</param> /// <param name="channelSettings">The new settings for the channel.</param> public static void setChannelSettings(this SmcSettings settings, SmcChannel channel, SmcChannelSettings channelSettings) { switch (channel) { case SmcChannel.Analog1: settings.analog1 = channelSettings; break; case SmcChannel.Analog2: settings.analog2 = channelSettings; break; case SmcChannel.Rc1: settings.rc1 = channelSettings; break; case SmcChannel.Rc2: settings.rc2 = channelSettings; break; default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Gets the state of the specified channel. /// </summary> /// <param name="vars">The state of the device.</param> /// <param name="channel">Specifies what channel to fetch.</param> /// <returns>The state of the specified channel.</returns> public static SmcChannelVariables getChannel(this SmcVariables vars, SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return(vars.analog1); case SmcChannel.Analog2: return(vars.analog2); case SmcChannel.Rc1: return(vars.rc1); case SmcChannel.Rc2: return(vars.rc2); default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Determines whether the specified channel is directly used to control the /// motor speed (i.e. it is a Throttle or Steering input). /// </summary> /// <param name="channel">Specifies the channel.</param> /// <param name="inputMode">The input mode of the device (Serial/USB, Analog, RC).</param> /// <param name="mixingMode">The mixing mode of the device (None, Left, Right).</param> /// <returns>True if and only if the channel controls the motor speed.</returns> public static bool controlsMotorSpeed(this SmcChannel channel, SmcInputMode inputMode, SmcMixingMode mixingMode) { if (inputMode == SmcInputMode.Analog) { return(channel == SmcChannel.Analog1 || (mixingMode != SmcMixingMode.None && channel == SmcChannel.Analog2)); } else if (inputMode == SmcInputMode.RC) { return(channel == SmcChannel.Rc1 || (mixingMode != SmcMixingMode.None && channel == SmcChannel.Rc2)); } else { // inputMode should be serial/USB return(false); } }
/// <summary> /// Returns the default settings for the given channel. /// </summary> /// <param name="channel"></param> /// <returns></returns> public static SmcChannelSettings defaults(SmcChannel channel) { if (channel.type() == SmcChannelType.Analog) { return SmcChannelSettings.defaultAnalogSettings(); } else { return SmcChannelSettings.defaultRCSettings(); } }
/// <summary> /// Gets the settings for the specified channel. /// </summary> /// <param name="settings">The settings of the device.</param> /// <param name="channel">Specifies what channel to fetch.</param> /// <returns>The settings of the specified channel.</returns> public static SmcChannelSettings getChannelSettings(this SmcSettings settings, SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return settings.analog1; case SmcChannel.Analog2: return settings.analog2; case SmcChannel.Rc1: return settings.rc1; case SmcChannel.Rc2: return settings.rc2; default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Gets the settings for the specified channel. /// </summary> /// <param name="settings">The settings of the device.</param> /// <param name="channel">Specifies what channel to fetch.</param> /// <returns>The settings of the specified channel.</returns> public static SmcChannelSettings getChannelSettings(this SmcSettings settings, SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return(settings.analog1); case SmcChannel.Analog2: return(settings.analog2); case SmcChannel.Rc1: return(settings.rc1); case SmcChannel.Rc2: return(settings.rc2); default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Returns true if the specified channel is a limit or kill switch and /// it is currently active. This information comes from the limitStatus /// register. /// </summary> public static bool switchActive(this SmcVariables vars, SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return (vars.limitStatus & SmcLimitStatus.Analog1) != 0; case SmcChannel.Analog2: return (vars.limitStatus & SmcLimitStatus.Analog2) != 0; case SmcChannel.Rc1: return (vars.limitStatus & SmcLimitStatus.Rc1) != 0; case SmcChannel.Rc2: return (vars.limitStatus & SmcLimitStatus.Rc2) != 0; default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
/// <summary> /// Gets the state of the specified channel. /// </summary> /// <param name="vars">The state of the device.</param> /// <param name="channel">Specifies what channel to fetch.</param> /// <returns>The state of the specified channel.</returns> public static SmcChannelVariables getChannel(this SmcVariables vars, SmcChannel channel) { switch (channel) { case SmcChannel.Analog1: return vars.analog1; case SmcChannel.Analog2: return vars.analog2; case SmcChannel.Rc1: return vars.rc1; case SmcChannel.Rc2: return vars.rc2; default: throw new Exception("Unknown Channel: " + channel.ToString()); } }
private static void parseChannel(Tag tag, SmcChannel channel, string name, SmcChannelSettings cs, List<string> warnings) { if (assertChild(tag, name, warnings)) { Tag channelTag = tag.children[name]; parseBool(channelTag, "Invert", ref cs.invert, warnings); if (assertValue(channelTag, "AlternateUse", warnings)) { try { cs.alternateUse = (SmcChannelAlternateUse)Enum.Parse(typeof(SmcChannelAlternateUse), channelTag.values["AlternateUse"]); } catch { warnings.Add("Invalid AlternateUse value \"" + channelTag.values["AlternateUse"] + "\"."); } } if (channel.type() == SmcChannelType.Analog && assertValue(channelTag, "PinMode", warnings)) { try { cs.pinMode = (SmcPinMode)Enum.Parse(typeof(SmcPinMode), channelTag.values["PinMode"]); } catch { warnings.Add("Invalid PinMode value \"" + channelTag.values["PinMode"] + "\"."); } } parseU8(channelTag, "ScalingDegree", ref cs.scalingDegree, warnings); parseRange(channelTag, "Error", ref cs.errorMin, ref cs.errorMax, warnings); parseRange(channelTag, "Input", ref cs.inputMin, ref cs.inputMax, warnings); parseRange(channelTag, "InputNeutral", ref cs.inputNeutralMin, ref cs.inputNeutralMax, warnings); } }