private static ActionOnDevice laterSetMotorLimit(SmcMotorLimit limit) { String previousArg = argEnumerator.Current; UInt16 value = nextArgumentAsU16(); bool brakeDuration = (limit & (SmcMotorLimit)3) == SmcMotorLimit.BrakeDuration; if (!brakeDuration && value > 3200) { throw new ArgumentOutOfRangeException("Maximum value allowed for " + previousArg + " is 3200."); } bool directionSpecified = (limit & (SmcMotorLimit.ForwardOnly | SmcMotorLimit.ReverseOnly)) != 0; return(delegate(Smc device) { // This is the line that actually sets the motor limit. SmcSetMotorLimitProblem problem = device.setMotorLimit(limit, value); bool forwardConflict = 0 != (problem & SmcSetMotorLimitProblem.ForwardConflict); bool reverseConflict = 0 != (problem & SmcSetMotorLimitProblem.ReverseConflict); if (directionSpecified) { // The user specified a direction, so at most one of the tooDangerous booleans should be set. if (forwardConflict || reverseConflict) { Console.Error.WriteLine("warning: specified value for " + previousArg + " conflicted with the hard limit, so the hard limit was used instead."); } } else { // The user specified no direction, so any of the tooDangerous booleans could be set. if (reverseConflict) { Console.Error.WriteLine("warning: specified value for " + previousArg + " conflicted with the hard limit for reverse, so the hard limit for reverse was used instead."); } if (forwardConflict) { Console.Error.WriteLine("warning: specified value for " + previousArg + " conflicted with the hard limit for forward, so the hard limit for forward was used instead."); } } }); }
/// <summary> /// Temporarily sets a motor limit. This change will last until the /// next time the device resets, or until another setMotorLimit command /// is issued which changes the limit. This function will not violate /// the hard motor limits that are stored in flash (with setSmcSettings). /// </summary> public SmcSetMotorLimitProblem setMotorLimit(SmcMotorLimit limit, UInt16 value) { Byte[] buffer = new Byte[1] { 0 }; // This should be the same as the code in actionSetMotorLimit in SmcCmd. if ((byte)limit >= 12) { throw new ArgumentException("Invalid limit ID.", "limit"); } if ((limit & (SmcMotorLimit)3) == SmcMotorLimit.BrakeDuration) { // Divide by 4 because the user will specify it in ms but the device expects // it in units of 4ms for this command. Round up to err on the side of making // it safer (that's the +3). value = (UInt16)((value + 3) / 4); } else if (value > 3200) { throw new ArgumentOutOfRangeException("value", "Maximum value allowed for MaxAcceleration, MaxDeceleration, or MaxSpeed is 3200."); } try { UInt32 lengthTransferred = controlTransfer(0xC0, (byte)SmcRequest.SetMotorLimit, value, (byte)limit, buffer); if (lengthTransferred != 1) { throw new Exception("Expected to receive 1 byte but received " + lengthTransferred + " bytes."); } return((SmcSetMotorLimitProblem)buffer[0]); } catch (Exception exception) { throw new Exception("There was an error clearing the safe start violation.", exception); } }
private static ActionOnDevice laterSetMotorLimit(SmcMotorLimit limit) { String previousArg = argEnumerator.Current; UInt16 value = nextArgumentAsU16(); bool brakeDuration = (limit & (SmcMotorLimit)3) == SmcMotorLimit.BrakeDuration; if (!brakeDuration && value > 3200) { throw new ArgumentOutOfRangeException("Maximum value allowed for " + previousArg + " is 3200."); } bool directionSpecified = (limit & (SmcMotorLimit.ForwardOnly | SmcMotorLimit.ReverseOnly)) != 0; return delegate(Smc device) { // This is the line that actually sets the motor limit. SmcSetMotorLimitProblem problem = device.setMotorLimit(limit, value); bool forwardConflict = 0 != (problem & SmcSetMotorLimitProblem.ForwardConflict); bool reverseConflict = 0 != (problem & SmcSetMotorLimitProblem.ReverseConflict); if (directionSpecified) { // The user specified a direction, so at most one of the tooDangerous booleans should be set. if (forwardConflict || reverseConflict) { Console.Error.WriteLine("warning: specified value for " + previousArg + " conflicted with the hard limit, so the hard limit was used instead."); } } else { // The user specified no direction, so any of the tooDangerous booleans could be set. if (reverseConflict) { Console.Error.WriteLine("warning: specified value for " + previousArg + " conflicted with the hard limit for reverse, so the hard limit for reverse was used instead."); } if (forwardConflict) { Console.Error.WriteLine("warning: specified value for " + previousArg + " conflicted with the hard limit for forward, so the hard limit for forward was used instead."); } } }; }
/// <summary> /// Temporarily sets a motor limit. This change will last until the /// next time the device resets, or until another setMotorLimit command /// is issued which changes the limit. This function will not violate /// the hard motor limits that are stored in flash (with setSmcSettings). /// </summary> public SmcSetMotorLimitProblem setMotorLimit(SmcMotorLimit limit, UInt16 value) { Byte[] buffer = new Byte[1]{ 0 }; // This should be the same as the code in actionSetMotorLimit in SmcCmd. if ((byte)limit >= 12) { throw new ArgumentException("Invalid limit ID.", "limit"); } if ((limit & (SmcMotorLimit)3) == SmcMotorLimit.BrakeDuration) { // Divide by 4 because the user will specify it in ms but the device expects // it in units of 4ms for this command. Round up to err on the side of making // it safer (that's the +3). value = (UInt16)((value + 3) / 4); } else if (value > 3200) { throw new ArgumentOutOfRangeException("value", "Maximum value allowed for MaxAcceleration, MaxDeceleration, or MaxSpeed is 3200."); } try { UInt32 lengthTransferred = controlTransfer(0xC0, (byte)SmcRequest.SetMotorLimit, value, (byte)limit, buffer); if (lengthTransferred != 1) { throw new Exception("Expected to receive 1 byte but received " + lengthTransferred + " bytes."); } return (SmcSetMotorLimitProblem)buffer[0]; } catch (Exception exception) { throw new Exception("There was an error clearing the safe start violation.", exception); } }