Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit f45bd519 authored by Markus QUARITSCH's avatar Markus QUARITSCH
Browse files

implementing more aaux classes in c# project

parent ef018ec6
No related branches found
No related tags found
No related merge requests found
Showing
with 2038 additions and 0 deletions
// Copyright 2017 European Union.
// Licensed under the EUPL (the 'Licence');
//
// * You may not use this work except in compliance with the Licence.
// * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
// * Unless required by applicable law or agreed to in writing,
// software distributed under the Licence is distributed on an "AS IS" basis,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the LICENSE.txt for the specific language governing permissions and limitations.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules.Electrics;
namespace Electrics
{
public class AlternatorMap : IAlternatorMap
{
private readonly string filePath;
private List<MapPoint> _map = new List<MapPoint>();
private List<double> _yRange;
private List<double> _xRange;
private double _minX, _minY, _maxX, _maxY;
// Required Action Test or Interpolation Type
public bool OnBoundaryYInterpolatedX(double x, double y)
{
return _yRange.Contains(y) && !_xRange.Contains(x);
}
public bool OnBoundaryXInterpolatedY(double x, double y)
{
return !_yRange.Contains(y) && _xRange.Contains(x);
}
public bool ONBoundaryXY(double x, double y)
{
return (from sector in _map
where sector.Y == y && sector.x == x
select sector).Count() == 1;
}
// Determine Value Methods
private double GetOnBoundaryXY(double x, double y)
{
return (from sector in _map
where sector.Y == y && sector.x == x
select sector).First().v;
}
private double GetOnBoundaryYInterpolatedX(double x, double y)
{
double x0, x1, v0, v1, slope, dx;
x0 = (from p in _xRange
orderby p
where p < x
select p).Last();
x1 = (from p in _xRange
orderby p
where p > x
select p).First();
dx = x1 - x0;
v0 = GetOnBoundaryXY(x0, y);
v1 = GetOnBoundaryXY(x1, y);
slope = (v1 - v0) / (x1 - x0);
return v0 + ((x - x0) * slope);
}
private double GetOnBoundaryXInterpolatedY(double x, double y)
{
double y0, y1, v0, v1, dy, v, slope;
y0 = (from p in _yRange
orderby p
where p < y
select p).Last();
y1 = (from p in _yRange
orderby p
where p > y
select p).First();
dy = y1 - y0;
v0 = GetOnBoundaryXY(x, y0);
v1 = GetOnBoundaryXY(x, y1);
slope = (v1 - v0) / (y1 - y0);
v = v0 + ((y - y0) * slope);
return v;
}
private double GetBiLinearInterpolatedValue(double x, double y)
{
double q11, q12, q21, q22, x1, x2, y1, y2, r1, r2, p;
y1 = (from mapSector in _map
where mapSector.Y < y
select mapSector).Last().Y;
y2 = (from mapSector in _map
where mapSector.Y > y
select mapSector).First().Y;
x1 = (from mapSector in _map
where mapSector.x < x
select mapSector).Last().x;
x2 = (from mapSector in _map
where mapSector.x > x
select mapSector).First().x;
q11 = GetOnBoundaryXY(x1, y1);
q12 = GetOnBoundaryXY(x1, y2);
q21 = GetOnBoundaryXY(x2, y1);
q22 = GetOnBoundaryXY(x2, y2);
r1 = ((x2 - x) / (x2 - x1)) * q11 + ((x - x1) / (x2 - x1)) * q21;
r2 = ((x2 - x) / (x2 - x1)) * q12 + ((x - x1) / (x2 - x1)) * q22;
p = ((y2 - y) / (y2 - y1)) * r1 + ((y - y1) / (y2 - y1)) * r2;
return p;
}
// Utilities
private void fillMapWithDefaults()
{
_map.Add(new MapPoint(10, 1500, 0.615));
_map.Add(new MapPoint(27, 1500, 0.7));
_map.Add(new MapPoint(53, 1500, 0.1947));
_map.Add(new MapPoint(63, 1500, 0.0));
_map.Add(new MapPoint(68, 1500, 0.0));
_map.Add(new MapPoint(125, 1500, 0.0));
_map.Add(new MapPoint(136, 1500, 0.0));
_map.Add(new MapPoint(10, 2000, 0.62));
_map.Add(new MapPoint(27, 2000, 0.7));
_map.Add(new MapPoint(53, 2000, 0.3));
_map.Add(new MapPoint(63, 2000, 0.1462));
_map.Add(new MapPoint(68, 2000, 0.692));
_map.Add(new MapPoint(125, 2000, 0.0));
_map.Add(new MapPoint(136, 2000, 0.0));
_map.Add(new MapPoint(10, 4000, 0.64));
_map.Add(new MapPoint(27, 4000, 0.6721));
_map.Add(new MapPoint(53, 4000, 0.7211));
_map.Add(new MapPoint(63, 4000, 0.74));
_map.Add(new MapPoint(68, 4000, 0.7352));
_map.Add(new MapPoint(125, 4000, 0.68));
_map.Add(new MapPoint(136, 4000, 0.6694));
_map.Add(new MapPoint(10, 6000, 0.53));
_map.Add(new MapPoint(27, 6000, 0.5798));
_map.Add(new MapPoint(53, 6000, 0.656));
_map.Add(new MapPoint(63, 6000, 0.6853));
_map.Add(new MapPoint(68, 6000, 0.7));
_map.Add(new MapPoint(125, 6000, 0.6329));
_map.Add(new MapPoint(136, 6000, 0.62));
_map.Add(new MapPoint(10, 7000, 0.475));
_map.Add(new MapPoint(27, 7000, 0.5337));
_map.Add(new MapPoint(53, 7000, 0.6235));
_map.Add(new MapPoint(63, 7000, 0.658));
_map.Add(new MapPoint(68, 7000, 0.6824));
_map.Add(new MapPoint(125, 7000, 0.6094));
_map.Add(new MapPoint(136, 7000, 0.5953));
}
private void getMapRanges()
{
;/* Cannot convert AssignmentStatementSyntax, System.NotImplementedException: Conversion for query clause with kind 'DistinctClause' not implemented
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.<>c__DisplayClass99_0.<ConvertQueryBodyClause>b__0(QueryClauseSyntax _)
at ICSharpCode.CodeConverter.Util.ObjectExtensions.TypeSwitch[TBaseType,TDerivedType1,TDerivedType2,TDerivedType3,TDerivedType4,TResult](TBaseType obj, Func`2 matchFunc1, Func`2 matchFunc2, Func`2 matchFunc3, Func`2 matchFunc4, Func`2 defaultFunc)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.ConvertQueryBodyClause(QueryClauseSyntax node)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at Microsoft.CodeAnalysis.SyntaxList`1.CreateNode(IEnumerable`1 nodes)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitQueryExpression(QueryExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.QueryExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitQueryExpression(QueryExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.QueryExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitParenthesizedExpression(ParenthesizedExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.ParenthesizedExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitParenthesizedExpression(ParenthesizedExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.ParenthesizedExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.MemberAccessExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.MemberAccessExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitInvocationExpression(InvocationExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.InvocationExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitInvocationExpression(InvocationExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.InvocationExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.MethodBodyVisitor.VisitAssignmentStatement(AssignmentStatementSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.AssignmentStatementSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingMethodBodyVisitor.ConvertWithTrivia(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingMethodBodyVisitor.DefaultVisit(SyntaxNode node)
Input:
_yRange = (From coords As MapPoint In _map Order By coords.Y Select coords.Y Distinct).ToList()
*/
;/* Cannot convert AssignmentStatementSyntax, System.NotImplementedException: Conversion for query clause with kind 'DistinctClause' not implemented
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.<>c__DisplayClass99_0.<ConvertQueryBodyClause>b__0(QueryClauseSyntax _)
at ICSharpCode.CodeConverter.Util.ObjectExtensions.TypeSwitch[TBaseType,TDerivedType1,TDerivedType2,TDerivedType3,TDerivedType4,TResult](TBaseType obj, Func`2 matchFunc1, Func`2 matchFunc2, Func`2 matchFunc3, Func`2 matchFunc4, Func`2 defaultFunc)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.ConvertQueryBodyClause(QueryClauseSyntax node)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at Microsoft.CodeAnalysis.SyntaxList`1.CreateNode(IEnumerable`1 nodes)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitQueryExpression(QueryExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.QueryExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitQueryExpression(QueryExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.QueryExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitParenthesizedExpression(ParenthesizedExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.ParenthesizedExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitParenthesizedExpression(ParenthesizedExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.ParenthesizedExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.MemberAccessExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.MemberAccessExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.NodesVisitor.VisitInvocationExpression(InvocationExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.InvocationExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingNodesVisitor.DefaultVisit(SyntaxNode node)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.VisitInvocationExpression(InvocationExpressionSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.InvocationExpressionSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at ICSharpCode.CodeConverter.CSharp.VisualBasicConverter.MethodBodyVisitor.VisitAssignmentStatement(AssignmentStatementSyntax node)
at Microsoft.CodeAnalysis.VisualBasic.Syntax.AssignmentStatementSyntax.Accept[TResult](VisualBasicSyntaxVisitor`1 visitor)
at Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxVisitor`1.Visit(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingMethodBodyVisitor.ConvertWithTrivia(SyntaxNode node)
at ICSharpCode.CodeConverter.CSharp.CommentConvertingMethodBodyVisitor.DefaultVisit(SyntaxNode node)
Input:
_xRange = (From coords As MapPoint In _map Order By coords.x Select coords.x Distinct).ToList()
*/
_minX = _xRange.First();
_maxX = _xRange.Last();
_minY = _yRange.First();
_maxY = _yRange.Last();
}
// Single entry point to determine Value on map
public double GetValue(double x, double y)
{
if (x < _minX || x > _maxX || y < _minY || y > _maxY) {
// OnAuxiliaryEvent(String.Format("Alternator Map Limiting : RPM{0}, AMPS{1}",x,y),AdvancedAuxiliaryMessageType.Warning)
// Limiting
if (x < _minX)
x = _minX;
if (x > _maxX)
x = _maxX;
if (y < _minY)
y = _minY;
if (y > _maxY)
y = _maxY;
}
// Satisfies both data points - non interpolated value
if (ONBoundaryXY(x, y))
return GetOnBoundaryXY(x, y);
// Satisfies only x or y - single interpolation value
if (OnBoundaryXInterpolatedY(x, y))
return GetOnBoundaryXInterpolatedY(x, y);
if (OnBoundaryYInterpolatedX(x, y))
return GetOnBoundaryYInterpolatedX(x, y);
// satisfies no data points - Bi-Linear interpolation
return GetBiLinearInterpolatedValue(x, y);
}
public string ReturnDefaultMapValueTests()
{
var sb = new StringBuilder();
// All Sector Values
sb.AppendLine("All Values From Map");
sb.AppendLine("-------------------");
foreach (var xr in _xRange) {
foreach (var yr in _yRange)
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", xr, yr, GetValue(xr, yr)));
}
sb.AppendLine("");
sb.AppendLine("Four Corners with interpolated other");
sb.AppendLine("-------------------");
var x = 1500.0;
var y = 18.5;
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", x, y, GetValue(x, y)));
x = 7000;
y = 96.5;
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", x, y, GetValue(x, y)));
x = 1750;
y = 10;
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", x, y, GetValue(x, y)));
x = 6500;
y = 10;
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", x, y, GetValue(x, y)));
sb.AppendLine("");
sb.AppendLine("Interpolated both");
sb.AppendLine("-------------------");
double mx, my;
int x2, y2;
for (x2 = 0; x2 <= _xRange.Count - 2; x2++) {
for (y2 = 0; y2 <= _yRange.Count - 2; y2++) {
mx = _xRange[x2] + (_xRange[x2 + 1] - _xRange[x2]) / 2;
my = _yRange[y2] + (_yRange[y2 + 1] - _yRange[y2]) / 2;
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", mx, my, GetValue(mx, my)));
}
}
sb.AppendLine("");
sb.AppendLine("MIKE -> 40 & 1000");
sb.AppendLine("-------------------");
x = 1000;
y = 40;
sb.AppendLine(string.Format("X:{0}, Y:{1}, V:{2}", x, y, GetValue(x, y)));
return sb.ToString();
}
// Constructors
public AlternatorMap(string filepath)
{
this.filePath = filepath;
Initialise();
getMapRanges();
}
private class MapPoint
{
public double Y;
public double x;
public double v;
public MapPoint(double y, double x, double v)
{
this.Y = y;
this.x = x;
this.v = v;
}
}
// Get Alternator Efficiency
public AlternatorMapValues GetEfficiency(double rpm, Ampere amps)
{
return new AlternatorMapValues(GetValue(rpm, amps.Value()));
}
// Initialises the map.
public bool Initialise()
{
if (File.Exists(filePath)) {
using (StreamReader sr = new StreamReader(filePath)) {
// get array og lines fron csv
var lines = sr.ReadToEnd().Split(new [] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
// Must have at least 2 entries in map to make it usable [dont forget the header row]
if (lines.Count() < 3)
throw new ArgumentException("Insufficient rows in csv to build a usable map");
_map = new List<MapPoint>();
var firstline = true;
foreach (var line in lines) {
if (!firstline) {
// Advanced Alternator Source Check.
if (line.Contains("[MODELSOURCE"))
break;
// split the line
string[] elements = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
// 3 entries per line required
if ((elements.Length != 3))
throw new ArgumentException("Incorrect number of values in csv file");
// add values to map
// Create AlternatorKey
var newPoint = new MapPoint(float.Parse(elements[0], CultureInfo.InvariantCulture), float.Parse(elements[1], CultureInfo.InvariantCulture), float.Parse(elements[2], CultureInfo.InvariantCulture));
_map.Add(newPoint);
}
firstline = false;
}
}
return true;
}
throw new ArgumentException("Supplied input file does not exist");
}
// Public Events
public event AuxiliaryEventEventHandler AuxiliaryEvent;
//public delegate void AuxiliaryEventEventHandler(ref object sender, string message, AdvancedAuxiliaryMessageType messageType);
protected void OnAuxiliaryEvent(string message, AdvancedAuxiliaryMessageType messageType)
{
object alternatorMap = this;
AuxiliaryEvent?.Invoke(ref alternatorMap, message, messageType);
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
namespace Electrics
{
// Model based on CombinedALTS_V02_Editable.xlsx
public class Alternator : IAlternator
{
private ICombinedAlternatorSignals signals;
// D6
public string AlternatorName { get; set; }
// G6
public double PulleyRatio { get; set; }
// C10-D15
public List<AltUserInput> InputTable2000 { get; set; } = new List<AltUserInput>();
// F10-G15
public List<AltUserInput> InputTable4000 { get; set; } = new List<AltUserInput>();
// I10-J15
public List<AltUserInput> InputTable6000 { get; set; } = new List<AltUserInput>();
// M10-N15
public List<Table4Row> RangeTable { get; set; } = new List<Table4Row>();
// S9
public double SpindleSpeed
{
get { return signals.CrankRPM * PulleyRatio; }
}
// S10
public double Efficiency
{
get {
// First build RangeTable, table 4
InitialiseRangeTable();
CalculateRangeTable();
// Calculate ( Interpolate ) Efficiency
var range = RangeTable.Select(s => new AltUserInput(s.RPM, s.Efficiency)).ToList();
return Alternator.Iterpolate(range, Convert.ToSingle(SpindleSpeed));
}
}
// Constructors
public Alternator() { }
public Alternator(ICombinedAlternatorSignals isignals, List<ICombinedAlternatorMapRow> inputs)
{
if (isignals == null)
throw new ArgumentException("Alternator - ISignals supplied is nothing");
signals = isignals;
AlternatorName = inputs.First().AlternatorName;
PulleyRatio = inputs.First().PulleyRatio;
var values2k = inputs.Where(x => x.RPM == 2000)
.Select(x => new KeyValuePair<double, double>(x.Amps, x.Efficiency))
.ToDictionary(x => x.Key, x => x.Value);
var values4k = inputs.Where(x => x.RPM == 4000)
.Select(x => new KeyValuePair<double, double>(x.Amps, x.Efficiency))
.ToDictionary(x => x.Key, x => x.Value);
var values6k = inputs.Where(x => x.RPM == 6000)
.Select(x => new KeyValuePair<double, double>(x.Amps, x.Efficiency))
.ToDictionary(x => x.Key, x => x.Value);
BuildInputTable(values2k, InputTable2000);
BuildInputTable(values4k, InputTable4000);
BuildInputTable(values6k, InputTable6000);
CreateRangeTable();
}
public static double Iterpolate(List<AltUserInput> values, double x)
{
var lowestX = values.Min(m => m.Amps);
var highestX = values.Max(m => m.Amps);
// Out of range, returns efficiency for lowest
if (x < lowestX)
return values.First(f => f.Amps == lowestX).Eff;
// Out of range, efficiency for highest
if (x > highestX)
return values.First(f => f.Amps == highestX).Eff;
// On Bounds check
if (values.Where(w => w.Amps == x).Count() == 1)
return values.First(w => w.Amps == x).Eff;
// OK, we need to interpolate.
var preKey = values.Last(l => l.Amps < x).Amps;
var postKey = values.First(l => l.Amps > x).Amps;
var preEff = values.First(f => f.Amps == preKey).Eff;
var postEff = values.First(f => f.Amps == postKey).Eff;
var deltaX = postKey - preKey;
var deltaEff = postEff - preEff;
// slopes
var effSlope = deltaEff / deltaX;
var retVal = ((x - preKey) * effSlope) + preEff;
return retVal;
}
private void CalculateRangeTable()
{
// M10=Row0-Rpm - N10=Row0-Eff
// M11=Row1-Rpm - N11=Row1-Eff
// M12=Row2-Rpm - N12=Row2-Eff - 2000
// M13=Row3-Rpm - N13=Row3-Eff - 4000
// M14=Row4-Rpm - N14=Row4-Eff - 6000
// M15=Row5-Rpm - N15=Row5-Eff
// M16=Row6-Rpm - N16=Row6-Eff
double N10, N11, N12, N13, N14, N15, N16;
double M10, M11, M12, M13, M14, M15, M16;
// EFFICIENCY
// 2000
N12 = Alternator.Iterpolate(InputTable2000, signals.CurrentDemandAmps.Value());
RangeTable[2].Efficiency = N12;
// 4000
N13 = Alternator.Iterpolate(InputTable4000, signals.CurrentDemandAmps.Value());
RangeTable[3].Efficiency = N13;
// 6000
N14 = Alternator.Iterpolate(InputTable6000, signals.CurrentDemandAmps.Value());
RangeTable[4].Efficiency = N14;
// Row0 & Row1 Efficiency =IF(N13>N12,0,MAX(N12:N14)) - Example Alt 1 N13=
N11 = N13 > N12 ? 0 : Math.Max(Math.Max(N12, N13), N14);
RangeTable[1].Efficiency = N11;
N10 = N11;
RangeTable[0].Efficiency = N10;
// Row 5 Efficiency
N15 = N13 > N14 ? 0 : Math.Max(Math.Max(N12, N13), N14);
RangeTable[5].Efficiency = N15;
// Row 6 - Efficiency
N16 = N15;
RangeTable[6].Efficiency = N16;
// RPM
// 2000 Row 2 - RPM
M12 = 2000;
RangeTable[2].RPM = M12;
// 4000 Row 3 - RPM
M13 = 4000;
RangeTable[3].RPM = M13;
// 6000 Row 4 - RPM
M14 = 6000;
RangeTable[4].RPM = M14;
// Row 1 - RPM
// NOTE: Update to reflect CombineALternatorSchematicV02 20150429
// IF(M12=IF(N12>N13,M12-((M12-M13)/(N12-N13))*(N12-N11),M12-((M12-M13)/(N12-N13))*(N12-N11)), M12-0.01, IF(N12>N13,M12-((M12-M13)/(N12-N13))*(N12-N11),M12-((M12-M13)/(N12-N13))*(N12-N11)))
M11 =
Convert.ToSingle(
N12 - N13 == 0
? 0
: (
M12 == (N12 > N13
? M12 - (M12 - M13) / (N12 - N13) * (N12 - N11)
: M12 - (M12 - M13) / (N12 - N13) * (N12 - N11))
? M12 - 0.01
: (N12 > N13
? M12 - (M12 - M13) / (N12 - N13) * (N12 - N11)
: M12 - (M12 - M13) / (N12 - N13) * (N12 - N11))));
RangeTable[1].RPM = M11;
// Row 0 - RPM
M10 = M11 < 1500 ? M11 - 1 : 1500;
RangeTable[0].RPM = M10;
// Row 5 - RPM
M15 =
Convert.ToSingle(
M14 == (N14 == 0 || N14 == N13
? M14 + 1
: (N13 > N14 ? (M14 - M13) / (N13 - N14) * N14 + M14 : (M14 - M13) / (N13 - N14) * (N14 - N15) + M14)
)
? M14 + 0.01
: (N14 == 0 || N14 == N13
? M14 + 1
: (N13 > N14 ? (M14 - M13) / (N13 - N14) * N14 + M14 : (M14 - M13) / (N13 - N14) * (N14 - N15) + M14)));
RangeTable[5].RPM = M15;
// Row 6 - RPM
M16 = M15 > 10000 ? M15 + 1 : 10000;
RangeTable[6].RPM = M16;
}
private void InitialiseRangeTable()
{
RangeTable[0].RPM = 0;
RangeTable[0].Efficiency = 0;
RangeTable[1].RPM = 0;
RangeTable[0].Efficiency = 0;
RangeTable[2].RPM = 2000;
RangeTable[0].Efficiency = 0;
RangeTable[3].RPM = 4000;
RangeTable[0].Efficiency = 0;
RangeTable[4].RPM = 6000;
RangeTable[0].Efficiency = 0;
RangeTable[5].RPM = 0;
RangeTable[0].Efficiency = 0;
RangeTable[6].RPM = 0;
RangeTable[0].Efficiency = 0;
}
private void CreateRangeTable()
{
RangeTable.Clear();
RangeTable.Add(new Table4Row(0, 0));
RangeTable.Add(new Table4Row(0, 0));
RangeTable.Add(new Table4Row(0, 0));
RangeTable.Add(new Table4Row(0, 0));
RangeTable.Add(new Table4Row(0, 0));
RangeTable.Add(new Table4Row(0, 0));
RangeTable.Add(new Table4Row(0, 0));
}
public void BuildInputTable(Dictionary<double, double> inputs, List<AltUserInput> targetTable)
{
double C11, C12, C13, C14, C15, D11, D12, D13, D14, D15;
targetTable.Clear();
// Row0
D14 = 0;
targetTable.Add(new AltUserInput(0, D14));
// Row1
targetTable.Add(new AltUserInput(inputs.OrderBy(x => x.Key).First().Key, inputs.OrderBy(x => x.Key).First().Value));
// Row2
targetTable.Add(
new AltUserInput(inputs.OrderBy(x => x.Key).Skip(1).First().Key, inputs.OrderBy(x => x.Key).Skip(1).First().Value));
// Row3
targetTable.Add(
new AltUserInput(inputs.OrderBy(x => x.Key).Skip(2).First().Key, inputs.OrderBy(x => x.Key).Skip(2).First().Value));
C11 = targetTable[1].Amps;
C12 = targetTable[2].Amps;
C13 = targetTable[3].Amps;
D11 = targetTable[1].Eff;
D12 = targetTable[2].Eff;
D13 = targetTable[3].Eff;
D14 = D12 > D13 ? 0 : Math.Max(Math.Max(D11, D12), D13);
// Row4 - Eff
targetTable.Add(new AltUserInput(0, D14));
// Row4 - Amps
// Should probably refactor this into some sort of helper/extension method
var numarray = new[] { D11, D12, D13 };
var maxD11_D13 = numarray.Max();
// =IF(OR(D13=0,D13=D12),C13+1,IF(D12>D13,((((C13-C12)/(D12-D13))*D13)+C13),((((C13-C12)/(D12-D13))*(D13-D14))+C13)))
C14 = (D13 == 0 || D13 == D12 || D13 == maxD11_D13)
? C13 + 1
: D12 > D13
? ((((C13 - C12) / (D12 - D13)) * D13) + C13)
: ((((C13 - C12) / (D12 - D13)) * (D13 - D14)) + C13);
targetTable[4].Amps = C14;
// Row5
C15 = C14 > 200 ? C14 + 1 : 200;
D15 = D14;
targetTable.Add(new AltUserInput(C15, D15));
// Row0
targetTable[0].Eff = D11;
}
public bool IsEqualTo(IAlternator other)
{
if (AlternatorName != other.AlternatorName) {
return false;
}
if (PulleyRatio != other.PulleyRatio) {
return false;
}
for (var i = 1; i <= 3; i++) {
if (InputTable2000[i].Eff != other.InputTable2000[i].Eff)
return false;
if (InputTable4000[i].Eff != other.InputTable4000[i].Eff)
return false;
if (InputTable6000[i].Eff != other.InputTable6000[i].Eff)
return false;
}
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules.Electrics;
namespace Electrics
{
public class CombinedAlternator : IAlternatorMap, ICombinedAlternator
{
private List<ICombinedAlternatorMapRow> map = new List<ICombinedAlternatorMapRow>();
public List<IAlternator> Alternators { get; set; } = new List<IAlternator>();
private List<IAlternator> OriginalAlternators = new List<IAlternator>();
private string FilePath;
private ICombinedAlternatorSignals altSignals;
private ISignals Signals;
private AlternatorMapValues AverageAlternatorsEfficiency;
// Interface Implementation
public AlternatorMapValues GetEfficiency(double CrankRPM, Ampere Amps)
{
altSignals.CrankRPM = CrankRPM;
altSignals.CurrentDemandAmps = (Amps.Value() / (double)Alternators.Count).SI<Ampere>();
AlternatorMapValues alternatorMapValues; /* TODO Change to default(_) if this is not a reference type */;
if (Signals == null || Signals.RunningCalc)
// If running calc cycle get efficiency from interpolation function
alternatorMapValues = new AlternatorMapValues(Convert.ToSingle(Alternators.Average(a => a.Efficiency) / (double)100));
else
// If running Pre calc cycle get an average of inputs
alternatorMapValues = AverageAlternatorsEfficiency;
if (alternatorMapValues.Efficiency <= 0)
alternatorMapValues = new AlternatorMapValues(0.01);
return alternatorMapValues;
}
public bool Initialise()
{
// From the map we construct this CombinedAlternator object and original CombinedAlternator Object
Alternators.Clear();
OriginalAlternators.Clear();
foreach (var alt in map.GroupBy(g => g.AlternatorName)) {
var altName = alt.First().AlternatorName;
var pulleyRatio = alt.First().PulleyRatio;
IAlternator alternator = new Alternator(altSignals, alt.ToList());
Alternators.Add(alternator);
}
return true;
}
// Constructors
public CombinedAlternator(string filePath, ISignals signals = null/* TODO Change to default(_) if this is not a reference type */)
{
string feedback = string.Empty;
this.Signals = signals;
if (!FilePathUtils.ValidateFilePath(filePath, ".aalt", ref feedback))
throw new ArgumentException(string.Format("Combined Alternator requires a valid .AALT filename. : {0}", feedback));
else
this.FilePath = filePath;
this.altSignals = new CombinedAlternatorSignals();
// IF file exists then read it otherwise create a default.
if (File.Exists(filePath) && InitialiseMap(filePath))
Initialise();
else {
// Create Default Map
CreateDefaultMap();
Initialise();
}
// Calculate alternators average which is used only in the pre-run
var efficiencySum = 0.0;
foreach (IAlternator alt in Alternators) {
efficiencySum += alt.InputTable2000.ElementAt(1).Eff;
efficiencySum += alt.InputTable2000.ElementAt(2).Eff;
efficiencySum += alt.InputTable2000.ElementAt(3).Eff;
efficiencySum += alt.InputTable4000.ElementAt(1).Eff;
efficiencySum += alt.InputTable4000.ElementAt(2).Eff;
efficiencySum += alt.InputTable4000.ElementAt(3).Eff;
efficiencySum += alt.InputTable6000.ElementAt(1).Eff;
efficiencySum += alt.InputTable6000.ElementAt(2).Eff;
efficiencySum += alt.InputTable6000.ElementAt(3).Eff;
}
var efficiencyAverage = efficiencySum / (Alternators.Count * 9);
AverageAlternatorsEfficiency = new AlternatorMapValues(efficiencyAverage / 100);
}
event TUGraz.VectoCore.BusAuxiliaries.Interfaces.AuxiliaryEventEventHandler IAuxiliaryEvent.AuxiliaryEvent
{
add {
throw new NotImplementedException();
}
remove {
throw new NotImplementedException();
}
}
// Helpers
private void CreateDefaultMap()
{
map.Clear();
map.Add(new CombinedAlternatorMapRow("Alt1", 2000, 10, 62, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 2000, 27, 70, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 2000, 53, 30, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 4000, 10, 64, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 4000, 63, 74, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 4000, 125, 68, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 6000, 10, 53, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 6000, 68, 70, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt1", 6000, 136, 62, 3.6));
map.Add(new CombinedAlternatorMapRow("Alt2", 2000, 10, 62, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 2000, 27, 70, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 2000, 53, 30, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 4000, 10, 64, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 4000, 63, 74, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 4000, 125, 68, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 6000, 10, 53, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 6000, 68, 70, 3));
map.Add(new CombinedAlternatorMapRow("Alt2", 6000, 136, 62, 3));
}
// Grid Management
private bool AddNewAlternator(List<ICombinedAlternatorMapRow> list, ref string feeback)
{
var altName = list.First().AlternatorName;
var pulleyRatio = list.First().PulleyRatio;
// Check alt does not already exist in list
if (Alternators.Any(w => w.AlternatorName == altName)) {
feeback = "This alternator already exists in in the list, operation not completed.";
return false;
}
IAlternator alternator = new Alternator(altSignals, list.ToList());
Alternators.Add(alternator);
return true;
}
public bool AddAlternator(List<ICombinedAlternatorMapRow> rows, ref string feedback)
{
if (!AddNewAlternator(rows, ref feedback)) {
feedback = string.Format("Unable to add new alternator : {0}", feedback);
return false;
}
return true;
}
public bool DeleteAlternator(string alternatorName, ref string feedback, bool CountValidation)
{
// Is this the last alternator, if so deny the user the right to remove it.
if (CountValidation && Alternators.Count < 2) {
feedback = "There must be at least one alternator remaining, operation aborted.";
return false;
}
if (Alternators.All(w => w.AlternatorName != alternatorName)) {
feedback = "This alternator does not exist";
return false;
}
IAlternator altToRemove = Alternators.First(w => w.AlternatorName == alternatorName);
int numAlternators = Alternators.Count;
Alternators.Remove(altToRemove);
if (Alternators.Count == numAlternators - 1) {
return true;
}
feedback = string.Format("The alternator {0} could not be removed : {1}", alternatorName, feedback);
return false;
}
public bool Save(string aaltPath)
{
var sb = new StringBuilder();
// write headers
sb.AppendLine("[AlternatorName],[RPM],[Amps],[Efficiency],[PulleyRatio]");
// write details
foreach (IAlternator alt in Alternators.OrderBy(o => o.AlternatorName)) {
// 2000 - IE Alt1,2000,10,50,3
for (var row = 1; row <= 3; row++) {
var amps = alt.InputTable2000[row].Amps;
var eff = alt.InputTable2000[row].Eff;
sb.Append(alt.AlternatorName + ",2000," + amps.ToString("0.000") + "," + eff.ToString("0.000") + "," + alt.PulleyRatio.ToString("0.000"));
sb.AppendLine("");
}
// 4000 - IE Alt1,2000,10,50,3
for (var row = 1; row <= 3; row++) {
var amps = alt.InputTable4000[row].Amps;
var eff = alt.InputTable4000[row].Eff;
sb.Append(alt.AlternatorName + ",4000," + amps.ToString("0.000") + "," + eff.ToString("0.000") + "," + alt.PulleyRatio.ToString("0.000"));
sb.AppendLine("");
}
// 6000 - IE Alt1,2000,10,50,3
for (var row = 1; row <= 3; row++) {
var amps = alt.InputTable6000[row].Amps;
var eff = alt.InputTable6000[row].Eff;
sb.Append(alt.AlternatorName + ",6000," + amps.ToString("0.000") + "," + eff.ToString("0.000") + "," + alt.PulleyRatio.ToString("0.000"));
sb.AppendLine("");
}
}
// Add Model Source
sb.AppendLine("[MODELSOURCE]");
sb.Append(ToString());
// Write the stream cotnents to a new file named "AllTxtFiles.txt"
using (StreamWriter outfile = new StreamWriter(aaltPath)) {
outfile.Write(sb.ToString());
}
return true;
}
private bool Load()
{
if (!InitialiseMap(FilePath))
return false;
return true;
}
// Initialises the map, only valid when loadingUI for first time in edit mode or always in operational mode.
private bool InitialiseMap(string filePath)
{
bool returnValue = false;
string[] elements;
if (File.Exists(filePath)) {
using (StreamReader sr = new StreamReader(filePath)) {
// get array og lines fron csv
string[] lines = sr.ReadToEnd().Split(new[] { Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
// Must have at least 2 entries in map to make it usable [dont forget the header row]
if ((lines.Count() < 10))
throw new ArgumentException("Insufficient rows in csv to build a usable map");
map = new List<ICombinedAlternatorMapRow>();
bool firstline = true;
foreach (string line in lines) {
if (!firstline) {
// Advanced Alternator Source Check.
if (line.Contains("[MODELSOURCE"))
break;
// split the line
elements = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
// 3 entries per line required
if ((elements.Length != 5))
throw new ArgumentException("Incorrect number of values in csv file");
// add values to map
map.Add(new CombinedAlternatorMapRow(elements[0], float.Parse(elements[1], CultureInfo.InvariantCulture), float.Parse(elements[2], CultureInfo.InvariantCulture), float.Parse(elements[3], CultureInfo.InvariantCulture), float.Parse(elements[4], CultureInfo.InvariantCulture)));
} else
firstline = false;
}
}
return true;
} else
throw new ArgumentException("Supplied input file does not exist");
return returnValue;
}
// Can be used to send messages to Vecto.
public event AuxiliaryEventEventHandler AuxiliaryEvent;
public delegate void AuxiliaryEventEventHandler(ref object sender, string message, AdvancedAuxiliaryMessageType messageType);
// This is used to generate a diagnostics output which enables the user to
// Determine if they beleive the resulting map is what is expected
// Basically it is a check against the model/Spreadsheet
public override string ToString()
{
StringBuilder sb = new StringBuilder();
string a1, a2, a3, e1, e2, e3;
const string vbTab = "\t";
foreach (Alternator alt in Alternators.OrderBy(o => o.AlternatorName)) {
sb.AppendLine("");
sb.AppendFormat("** {0} ** , PulleyRatio {1}", alt.AlternatorName, alt.PulleyRatio);
sb.AppendLine("");
sb.AppendLine("******************************************************************");
sb.AppendLine("");
int i = 1;
sb.AppendLine("Table 1 (2000)" + vbTab + "Table 2 (4000)" + vbTab + "Table 3 (6000)");
sb.AppendLine("Amps" + vbTab + "Eff" + vbTab + "Amps" + vbTab + "Eff" + vbTab + "Amps" + vbTab + "Eff" + vbTab);
sb.AppendLine("");
for (i = 1; i <= 3; i++) {
a1 = alt.InputTable2000[i].Amps.ToString("0");
e1 = alt.InputTable2000[i].Eff.ToString("0.000");
a2 = alt.InputTable4000[i].Amps.ToString("0");
e2 = alt.InputTable4000[i].Eff.ToString("0.000");
a3 = alt.InputTable6000[i].Amps.ToString("0");
e3 = alt.InputTable6000[i].Eff.ToString("0.000");
sb.AppendLine(a1 + vbTab + e1 + vbTab + a2 + vbTab + e2 + vbTab + a3 + vbTab + e3 + vbTab);
}
}
// sb.AppendLine("")
// sb.AppendLine("********* COMBINED EFFICIENCY VALUES **************")
// sb.AppendLine("")
// sb.AppendLine(vbTab + "RPM VALUES")
// sb.AppendLine("AMPS" + vbTab + "500" + vbTab + "1500" + vbTab + "2500" + vbTab + "3500" + vbTab + "4500" + vbTab + "5500" + vbTab + "6500" + vbTab + "7500")
// For a As Single = 1 To Alternators.Count * 50
// sb.Append(a.ToString("0") + vbTab)
// For Each r As Single In {500, 1500, 2500, 3500, 4500, 5500, 6500, 7500}
// Dim eff As Single = GetEfficiency(r, a).Efficiency
// sb.Append(eff.ToString("0.000") + vbTab)
// Next
// sb.AppendLine("")
// Next
return sb.ToString();
}
// Equality
public bool IsEqualTo(ICombinedAlternator other)
{
// Count Check.
if (this.Alternators.Count != other.Alternators.Count)
return false;
foreach (IAlternator alt in this.Alternators) {
// Can we find the same alternatorName in other
if (other.Alternators.Where(f => f.AlternatorName == alt.AlternatorName).Count() != 1)
return false;
// get the alternator to compare and compare it.
if (!alt.IsEqualTo(other.Alternators.First(f => f.AlternatorName == alt.AlternatorName)))
return false;
}
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
namespace Electrics
{
// This class is reflective of the stored entries for the combined alternator
// And is used by the Combined Alternator Form and any related classes.
public class CombinedAlternatorMapRow : ICombinedAlternatorMapRow
{
public string AlternatorName { get; set; }
public double RPM { get; set; }
public double Amps { get; set; }
public double Efficiency { get; set; }
public double PulleyRatio { get; set; }
// Constructors
public CombinedAlternatorMapRow()
{
}
public CombinedAlternatorMapRow(string alternatorName, double rpm, double amps, double efficiency, double pulleyRatio)
{
// Sanity Check
if (alternatorName.Trim().Length == 0)
throw new ArgumentException("Alternator name cannot be zero length");
if (efficiency < 0 | efficiency > 100)
throw new ArgumentException("Alternator Efficiency must be between 0 and 100");
if (pulleyRatio <= 0)
throw new ArgumentException("Alternator Pully ratio must be a positive number");
// Assignments
AlternatorName = alternatorName;
RPM = rpm;
Amps = amps;
Efficiency = efficiency;
PulleyRatio = pulleyRatio;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
using TUGraz.VectoCommon.Utils;
namespace Electrics
{
// Used by the CombinedAlternator class and any other related classes.
public class CombinedAlternatorSignals : ICombinedAlternatorSignals
{
public double CrankRPM { get; set; }
public Ampere CurrentDemandAmps { get; set; }
// Number of alternators in the Combined Alternator
public int NumberOfAlternators { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using System.ComponentModel;
using DownstreamModules.Electrics;
using TUGraz.VectoCommon.Utils;
// Copyright 2017 European Union.
// Licensed under the EUPL (the 'Licence');
//
// * You may not use this work except in compliance with the Licence.
// * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
// * Unless required by applicable law or agreed to in writing,
// software distributed under the Licence is distributed on an "AS IS" basis,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the LICENSE.txt for the specific language governing permissions and limitations.
namespace Electrics
{
/// <summary>
/// ''' Described a consumer of Alternator electrical power
/// ''' </summary>
/// ''' <remarks></remarks>
public class ElectricalConsumer : IElectricalConsumer
{
// Fields
private bool _BaseVehicle;
private string _Category;
private string _ConsumerName;
private double _NominalConsumptionAmps;
private int _NumberInActualVehicle;
private double _PhaseIdle_TractionOn;
private double _PowerNetVoltage;
private string _Info;
// Calculated
public double AvgConsumptionAmps { get; set; }
// Properties
public bool BaseVehicle
{
get {
return _BaseVehicle;
}
set {
_BaseVehicle = value;
NotifyPropertyChanged("BaseVehicle");
}
}
public string Category
{
get {
return _Category;
}
set {
_Category = value;
NotifyPropertyChanged("Category");
}
}
public string ConsumerName
{
get {
return _ConsumerName;
}
set {
_ConsumerName = value;
NotifyPropertyChanged("ConsumerName");
}
}
public double NominalConsumptionAmps
{
get {
return _NominalConsumptionAmps;
}
set {
_NominalConsumptionAmps = value;
NotifyPropertyChanged("NominalConsumptionAmps");
}
}
public int NumberInActualVehicle
{
get {
return _NumberInActualVehicle;
}
set {
_NumberInActualVehicle = value;
NotifyPropertyChanged("NumberInActualVehicle");
}
}
public double PhaseIdle_TractionOn
{
get {
return _PhaseIdle_TractionOn;
}
set {
_PhaseIdle_TractionOn = value;
NotifyPropertyChanged("PhaseIdle_TractionOn");
}
}
public double PowerNetVoltage
{
get {
return _PowerNetVoltage;
}
set {
_PowerNetVoltage = value;
NotifyPropertyChanged("PowerNetVoltage");
}
}
public string Info
{
get {
return _Info;
}
set {
_Info = value;
NotifyPropertyChanged("Info");
}
}
// Public class outputs
public Ampere TotalAvgConumptionAmps(double PhaseIdle_TractionOnBasedOnCycle = default(Double))
{
if (ConsumerName == "Doors per Door")
return NominalConsumptionAmps.SI<Ampere>() * (NumberInActualVehicle * PhaseIdle_TractionOnBasedOnCycle);
else
return NominalConsumptionAmps.SI<Ampere>() * (NumberInActualVehicle * PhaseIdle_TractionOn);
}
public Watt TotalAvgConsumptionInWatts(double PhaseIdle_TractionOnBasedOnCycle = 0.0)
{
return TotalAvgConumptionAmps(PhaseIdle_TractionOnBasedOnCycle) * PowerNetVoltage.SI<Volt>();
}
// Constructor
public ElectricalConsumer(bool BaseVehicle, string Category, string ConsumerName, double NominalConsumptionAmps, double PhaseIdle_TractionOn, double PowerNetVoltage, int numberInVehicle, string info)
{
// Illegal Value Check.
if (Category.Trim().Length == 0)
throw new ArgumentException("Category Name cannot be empty");
if (ConsumerName.Trim().Length == 0)
throw new ArgumentException("ConsumerName Name cannot be empty");
if (PhaseIdle_TractionOn < ElectricConstants.PhaseIdleTractionOnMin | PhaseIdle_TractionOn > ElectricConstants.PhaseIdleTractionMax)
throw new ArgumentException("PhaseIdle_TractionOn must have a value between 0 and 1");
if (NominalConsumptionAmps < ElectricConstants.NonminalConsumerConsumptionAmpsMin | NominalConsumptionAmps > ElectricConstants.NominalConsumptionAmpsMax)
throw new ArgumentException("NominalConsumptionAmps must have a value between 0 and 100");
if (PowerNetVoltage < ElectricConstants.PowenetVoltageMin | PowerNetVoltage > ElectricConstants.PowenetVoltageMax)
throw new ArgumentException("PowerNetVoltage must have a value between 6 and 48");
if (numberInVehicle < 0)
throw new ArgumentException("Cannot have less than 0 consumers in the vehicle");
// Good, now assign.
this.BaseVehicle = BaseVehicle;
this.Category = Category;
this.ConsumerName = ConsumerName;
this.NominalConsumptionAmps = NominalConsumptionAmps;
this.PhaseIdle_TractionOn = PhaseIdle_TractionOn;
this.PowerNetVoltage = PowerNetVoltage;
this.NumberInActualVehicle = numberInVehicle;
this.Info = info;
}
// Comparison Overrides
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
IElectricalConsumer other = (IElectricalConsumer)obj;
return this.ConsumerName == other.ConsumerName;
}
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public override int GetHashCode()
{
return 0;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string p)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p));
}
}
}
// Copyright 2017 European Union.
// Licensed under the EUPL (the 'Licence');
//
// * You may not use this work except in compliance with the Licence.
// * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
// * Unless required by applicable law or agreed to in writing,
// software distributed under the Licence is distributed on an "AS IS" basis,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the LICENSE.txt for the specific language governing permissions and limitations.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
using TUGraz.VectoCommon.Utils;
namespace Electrics
{
public class ElectricalConsumerList : IElectricalConsumerList
{
private List<IElectricalConsumer> _items = new List<IElectricalConsumer>();
private double _powernetVoltage;
private double _doorDutyCycleZeroToOne;
// Constructor
public ElectricalConsumerList(double powernetVoltage, double doorDutyCycle_ZeroToOne, bool createDefaultList = false)
{
_powernetVoltage = powernetVoltage;
if (createDefaultList)
_items = GetDefaultConsumerList();
_doorDutyCycleZeroToOne = doorDutyCycle_ZeroToOne;
}
// Transfers the Info comments from a default set of consumables to a live set.
// This way makes the comments not dependent on saved data.
public void MergeInfoData()
{
if (_items.Count != GetDefaultConsumerList().Count)
return;
List<IElectricalConsumer> dflt = GetDefaultConsumerList();
for (int idx = 0; idx <= _items.Count - 1; idx++)
_items[idx].Info = dflt[idx].Info;
}
// Initialise default set of consumers
public List<IElectricalConsumer> GetDefaultConsumerList()
{
// This populates the default settings as per engineering spreadsheet.
// Vehicle Basic Equipment' category can be added or remove by customers.
// At some time in the future, this may be removed and replace with file based consumer lists.
List<IElectricalConsumer> items = new List<IElectricalConsumer>();
IElectricalConsumer c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20;
c1 = (IElectricalConsumer)new ElectricalConsumer(false, "Doors", "Doors per Door", 3.0, 0.096339, _powernetVoltage, 3, "");
c2 = (IElectricalConsumer)new ElectricalConsumer(true, "Veh Electronics &Engine", "Controllers,Valves etc", 25.0, 1.0, _powernetVoltage, 1, "");
c3 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Radio City", 2.0, 0.8, _powernetVoltage, 1, "");
c4 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Radio Intercity", 5.0, 0.8, _powernetVoltage, 0, "");
c5 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Radio/Audio Tourism", 9.0, 0.8, _powernetVoltage, 0, "");
c6 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Fridge", 4.0, 0.5, _powernetVoltage, 0, "");
c7 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Kitchen Standard", 67.0, 0.05, _powernetVoltage, 0, "");
c8 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Interior lights City/ Intercity + Doorlights [Should be 1/m]", 1.0, 0.7, _powernetVoltage, 12, "1 Per metre length of bus");
c9 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "LED Interior lights ceiling city/Intercity + door [Should be 1/m]", 0.6, 0.7, _powernetVoltage, 0, "1 Per metre length of bus");
c10 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "Interior lights Tourism + reading [1/m]", 1.1, 0.7, _powernetVoltage, 0, "1 Per metre length of bus");
c11 = (IElectricalConsumer)new ElectricalConsumer(false, "Vehicle basic equipment", "LED Interior lights ceiling Tourism + LED reading [Should be 1/m]", 0.66, 0.7, _powernetVoltage, 0, "1 Per metre length of bus");
c12 = (IElectricalConsumer)new ElectricalConsumer(false, "Customer Specific Equipment", "External Displays Font/Side/Rear", 2.65017667844523, 1.0, _powernetVoltage, 4, "");
c13 = (IElectricalConsumer)new ElectricalConsumer(false, "Customer Specific Equipment", "Internal display per unit ( front side rear)", 1.06007067137809, 1.0, _powernetVoltage, 1, "");
c14 = (IElectricalConsumer)new ElectricalConsumer(false, "Customer Specific Equipment", "CityBus Ref EBSF Table4 Devices ITS No Displays", 9.3, 1.0, _powernetVoltage, 1, "");
c15 = (IElectricalConsumer)new ElectricalConsumer(false, "Lights", "Exterior Lights BULB", 7.4, 1.0, _powernetVoltage, 1, "");
c16 = (IElectricalConsumer)new ElectricalConsumer(false, "Lights", "Day running lights LED bonus", -0.723, 1.0, _powernetVoltage, 1, "");
c17 = (IElectricalConsumer)new ElectricalConsumer(false, "Lights", "Antifog rear lights LED bonus", -0.17, 1.0, _powernetVoltage, 1, "");
c18 = (IElectricalConsumer)new ElectricalConsumer(false, "Lights", "Position lights LED bonus", -1.2, 1.0, _powernetVoltage, 1, "");
c19 = (IElectricalConsumer)new ElectricalConsumer(false, "Lights", "Direction lights LED bonus", -0.3, 1.0, _powernetVoltage, 1, "");
c20 = (IElectricalConsumer)new ElectricalConsumer(false, "Lights", "Brake Lights LED bonus", -1.2, 1.0, _powernetVoltage, 1, "");
items.Add(c1);
items.Add(c2);
items.Add(c3);
items.Add(c4);
items.Add(c5);
items.Add(c6);
items.Add(c7);
items.Add(c8);
items.Add(c9);
items.Add(c10);
items.Add(c11);
items.Add(c12);
items.Add(c13);
items.Add(c14);
items.Add(c15);
items.Add(c16);
items.Add(c17);
items.Add(c18);
items.Add(c19);
items.Add(c20);
return items;
}
// Interface implementation
public double DoorDutyCycleFraction
{
get {
return _doorDutyCycleZeroToOne;
}
set {
_doorDutyCycleZeroToOne = value;
}
}
public List<IElectricalConsumer> Items
{
get {
return _items;
}
}
public void AddConsumer(IElectricalConsumer consumer)
{
if (!_items.Contains(consumer))
_items.Add(consumer);
else
throw new ArgumentException("Consumer Already Present in the list");
}
public void RemoveConsumer(IElectricalConsumer consumer)
{
if (_items.Contains(consumer))
_items.Remove(consumer);
else
throw new ArgumentException("Consumer Not In List");
}
public Ampere GetTotalAverageDemandAmps(bool excludeOnBase)
{
Ampere Amps;
if (excludeOnBase)
Amps = Items.Where(x => x.BaseVehicle == false)
.Sum(consumer => consumer.TotalAvgConumptionAmps(DoorDutyCycleFraction));
// Aggregate item In Items Where item.BaseVehicle = False Into Sum(item.TotalAvgConumptionAmps(DoorDutyCycleFraction))
else
Amps = Items.Sum(x => x.TotalAvgConumptionAmps(DoorDutyCycleFraction));
//Aggregate item In Items Into Sum(item.TotalAvgConumptionAmps(DoorDutyCycleFraction))
return Amps;
}
}
}
// Copyright 2017 European Union.
// Licensed under the EUPL (the 'Licence');
//
// * You may not use this work except in compliance with the Licence.
// * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
// * Unless required by applicable law or agreed to in writing,
// software distributed under the Licence is distributed on an "AS IS" basis,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the LICENSE.txt for the specific language governing permissions and limitations.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules.Electrics;
namespace Electrics
{
public class ElectricsUserInputsConfig : IElectricsUserInputsConfig
{
public double PowerNetVoltage { get; set; }
public string AlternatorMap { get; set; }
public double AlternatorGearEfficiency { get; set; }
public IElectricalConsumerList ElectricalConsumers { get; set; }
public int DoorActuationTimeSecond { get; set; }
public double StoredEnergyEfficiency { get; set; }
public IResultCard ResultCardIdle { get; set; }
public IResultCard ResultCardTraction { get; set; }
public IResultCard ResultCardOverrun { get; set; }
public bool SmartElectrical { get; set; }
public ElectricsUserInputsConfig(bool setToDefaults = false, VectoInputs vectoInputs = null/* TODO Change to default(_) if this is not a reference type */)
{
if (setToDefaults)
SetPropertiesToDefaults(vectoInputs);
}
public void SetPropertiesToDefaults(VectoInputs vectoInputs)
{
DoorActuationTimeSecond = 4;
StoredEnergyEfficiency = 0.935;
AlternatorGearEfficiency = 0.92;
PowerNetVoltage = vectoInputs.PowerNetVoltage.Value();
ResultCardIdle = new ResultCard(new List<SmartResult>());
ResultCardOverrun = new ResultCard(new List<SmartResult>());
ResultCardTraction = new ResultCard(new List<SmartResult>());
SmartElectrical = false;
AlternatorMap = string.Empty;
}
}
}
// Copyright 2017 European Union.
// Licensed under the EUPL (the 'Licence');
//
// * You may not use this work except in compliance with the Licence.
// * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
// * Unless required by applicable law or agreed to in writing,
// software distributed under the Licence is distributed on an "AS IS" basis,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the LICENSE.txt for the specific language governing permissions and limitations.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using DownstreamModules.Electrics;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules.Electrics;
namespace Electrics
{
public class ResultCard : IResultCard
{
private List<SmartResult> _results;
// Constructor
public ResultCard(List<SmartResult> results)
{
if (results == null)
throw new ArgumentException("A list of smart results must be supplied.");
_results = results;
}
// Public class outputs
public List<SmartResult> Results
{
get { return _results; }
}
public Ampere GetSmartCurrentResult(Ampere Amps)
{
if (_results.Count < 2)
return 10.SI<Ampere>();
return GetOrInterpolate(Amps.Value()).SI<Ampere>();
}
// Helpers
/// <summary>
/// ''' Gets or interpolates value (A)
/// ''' </summary>
/// ''' <param name="amps"></param>
/// ''' <returns></returns>
/// ''' <remarks></remarks>
private double GetOrInterpolate(double amps)
{
double pre;
double post;
double dAmps;
double dSmartAmps;
double smartAmpsSlope;
double smartAmps;
double maxKey;
double minKey;
maxKey = _results.Max().Amps;
minKey = _results.Min().Amps;
SmartResult compareKey = new SmartResult(amps, 0);
// Is on boundary check
if (_results.Contains(compareKey))
return _results.OrderBy(x => x.Amps).First(x => x.Amps == compareKey.Amps).SmartAmps;
// Is over map - Extrapolate
if (amps > maxKey) {
// get the entries before and after the supplied key
pre = (from a in _results
orderby a.Amps
where a.Amps < maxKey
select a).Last().Amps;
post = maxKey;
// get the delta values
dAmps = post - pre;
dSmartAmps = (from da in _results
orderby da.Amps
where da.Amps == post
select da).First().SmartAmps - (from da in _results
orderby da.Amps
where da.Amps == pre
select da).First().SmartAmps;
// calculate the slopes
smartAmpsSlope = dSmartAmps / dAmps;
// calculate the new values
smartAmps = ((amps - post) * smartAmpsSlope) + (from da in _results
orderby da.Amps
where da.Amps == post
select da).First().SmartAmps;
return smartAmps;
}
// Is under map - Extrapolate
if (amps < minKey) {
// get the entries before and after the supplied key
// Post is the first entry and pre is the penultimate to first entry
post = minKey;
pre = (from k in _results
orderby k.Amps
where k.Amps > minKey
select k).First().Amps;
// get the delta values
dAmps = post - pre;
dSmartAmps = (from da in _results
orderby da.Amps
where da.Amps == post
select da).First().SmartAmps - (from da in _results
orderby da.Amps
where da.Amps == pre
select da).First().SmartAmps;
// calculate the slopes
smartAmpsSlope = dSmartAmps / dAmps;
// calculate the new values
smartAmps = ((amps - post) * smartAmpsSlope) + (from da in _results
orderby da.Amps
where da.Amps == post
select da).First().SmartAmps;
return smartAmps;
}
// Is Inside map - Interpolate
// get the entries before and after the supplied rpm
pre = (from m in _results
orderby m.Amps
where m.Amps < amps
select m).Last().Amps;
post = (from m in _results
where m.Amps > amps
select m).First().Amps;
// get the delta values for rpm and the map values
dAmps = post - pre;
dSmartAmps = (from da in _results
orderby da.Amps
where da.Amps == post
select da).First().SmartAmps - (from da in _results
orderby da.Amps
where da.Amps == pre
select da).First().SmartAmps;
// calculate the slopes
smartAmpsSlope = dSmartAmps / dAmps;
// calculate the new values
smartAmps = ((amps - post) * smartAmpsSlope) + (from da in _results
orderby da.Amps
where da.Amps == post
select da).First().SmartAmps;
return smartAmps;
}
}
}
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualBasic;
public class FilePathUtils
{
public static string Left(string str, int length)
{
return str.Substring(0, Math.Min(length, str.Length));
}
public static string Right(string value, int length)
{
if (string.IsNullOrEmpty(value)) return string.Empty;
return value.Length <= length ? value : value.Substring(value.Length - length);
}
public static bool ValidateFilePath(string filePath, string expectedExtension, ref string message)
{
char[] illegalFileNameCharacters = new[] { '<', '>', ':', '"', '/', '\\', '|', '?', '*', '~' };
string detectedExtention = fileExtentionOnly(filePath);
string pathOnly = filePathOnly(filePath);
string fileNameOnlyWithExtension = fileNameOnly(filePath, true);
string fileNameOnlyNoExtension = fileNameOnly(filePath, false);
// Is this filePath empty
if (filePath.Trim().Length == 0 || Right(filePath, 1) == @"\") {
message = "A filename cannot be empty";
return false;
}
// Extension Expected, but not match
if (expectedExtension.Trim().Length > 0) {
if (string.Compare(expectedExtension, detectedExtention, true) != 0) {
message = string.Format("The file extension type does not match the expected type of {0}", expectedExtension);
return false;
}
}
// Extension Not Expected, but was supplied
if (expectedExtension.Trim().Length > 0) {
if (detectedExtention.Length == 0) {
message = string.Format("No Extension was supplied, but an extension of {0}, this is not required", detectedExtention);
return false;
}
}
// Illegal characters
if (!fileNameLegal(fileNameOnlyWithExtension)) {
message = string.Format("The filenames have one or more illegal characters");
return false;
}
message = "OK";
return true;
}
public static bool fileNameLegal(string fileName)
{
char[] illegalFileNameCharacters = new[] { '<', '>', ':', '"', '/', '\\', '|', '?', '*', '~' };
// Illegal characters
foreach (char ch in illegalFileNameCharacters) {
if (fileName.Contains(ch))
return false;
}
return true;
}
public static string ResolveFilePath(string vectoPath, string filename)
{
// No Vecto Path supplied
if (vectoPath == "")
return filename;
// This is not relative
if (filename.Contains(@":\"))
// Filepath is already absolute
return filename;
else
return Path.Combine(vectoPath, filename);// vectoPath & filename
}
/// <summary>
/// ''' File name without the path "C:\temp\TEST.txt" >> "TEST.txt" oder "TEST"
/// ''' </summary>
/// ''' <param name="filePath"></param>
/// ''' <param name="WithExtention"></param>
/// ''' <returns>Return file portion of the path, with or without the extension</returns>
/// ''' <remarks></remarks>
public static string fileNameOnly(string filePath, bool WithExtention)
{
int x;
x = filePath.LastIndexOf(@"\") + 1;
filePath = Right(filePath, filePath.Length - x);
if (!WithExtention) {
x = filePath.LastIndexOf(".");
if (x > 0)
filePath = Left(filePath, x);
}
return filePath;
}
/// <summary>
/// ''' Extension alone "C:\temp\TEST.txt" >> ".txt"
/// ''' </summary>
/// ''' <param name="filePath"></param>
/// ''' <returns>Extension alone Including the dot IE .EXT</returns>
/// ''' <remarks></remarks>
public static string fileExtentionOnly(string filePath)
{
int x;
x = filePath.LastIndexOf(".");
if (x == -1)
return "";
else
return Right(filePath, filePath.Length - x);
}
/// <summary>
/// ''' File Path alone "C:\temp\TEST.txt" >> "C:\temp\"
/// ''' "TEST.txt" >> ""
/// ''' </summary>
/// ''' <param name="filePath"></param>
/// ''' <returns>Filepath without the extension</returns>
/// ''' <remarks></remarks>
public static string filePathOnly(string filePath)
{
int x;
if (filePath == null || filePath.Length < 3 || filePath.Substring(1, 2) != @":\")
return "";
x = filePath.LastIndexOf(@"\");
return Left(filePath, x + 1);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment