Rev Warrior - 汽车性能辅助





0/5 (0投票)
一个帮助汽车爱好者调整其车辆的应用程序。
介绍
Rev Warrior 旨在帮助汽车性能发烧友充分发挥其轿车或卡车的性能。最基本的功能是,它是一个数据收集工具,利用超极本中的传感器以及(可选的)OBDII 连接来收集和分析性能数据,以帮助改装者从他们的车辆中压榨出最佳性能。虽然 Rev Warrior 将利用触摸屏界面并使用 WPF 打造出 Metro 风格的应用外观,但由于需要 OBDII 连接,它将是一个完整的桌面应用。与外部硬件通信所需的串行 API 在 WinRT 堆栈中不可用。
背景
在 Android 和 iOS 上有一些用于性能调优的应用,但它们的功能有限。OBDII 功能有时没有完全实现或难以使用,通常无法启动“性能测试”并记录其数据,也无法将不同测试的数据进行比较,以了解车辆配置的变化如何影响性能。作为一个尝试过其中一些应用的人,我发现它们很有用,但我很快就遇到了每个应用的局限性。为它们辩护的话,移动设备本身有限,所以要实现一个功能齐全、特性完整的数据采集应用程序是很困难的。因此,一个想法的雏形诞生了。
当我在 2012 年初最初想到这个点子时,主要问题之一是如何独立于车辆收集传感器数据。我曾考虑过开发一个移动应用,利用手机中的传感器将数据传递给在笔记本电脑上运行的应用。但这太复杂了,而且由于没有“主时钟”,要匹配数据点会很困难。给笔记本电脑增加一个传感器包可以解决这个问题,我考虑过将 Netduino 作为一个可能的解决方案。但我不是做硬件的,虽然我不会排除未来支持笔记本电脑的这种可能性,但这给我设置了一个我当时不愿意攀登的更高门槛。然后,超极本出现了……它拥有笔记本电脑的强大功能(因此可以编写功能齐全的应用),并结合了内置的传感器支持。我的问题终于有了解决方案,这个想法也终于有了转化为实际应用的载体。
应用基础
这只是该应用程序的初步设计文档,我欢迎您的提问、评论和建议。他人的意见对于将此应用变得实用至关重要,随着应用的开发,本文也将不断演进。
该应用将分为实时和分析两个部分。在应用的实时部分,用户将能够看到当前的性能参数,如果连接了适配器,可以管理和查看 OBDII 数据,设置性能测试的数据采集,以及在可配置的仪表盘上查看实时数据。仪表盘将提供一个镜像图像的选项,以便用户可以将设备放在车辆的仪表台上,以“抬头显示”模式查看信息。
该应用的重点将是性能数据采集。用户将能够设置要为一次测试收集的参数(包括设置和管理多辆车),然后“启动”该测试。一旦启动,软件将开始将汽车的性能参数记录到一个循环缓冲区中。如果只有超极本传感器可用(没有 OBDII 接口),这将仅限于加速度、方向和 GPS 数据。应用将缓冲性能数据,直到它检测到一个或多个参数发生显著变化,表明测试开始(例如,驾驶员猛踩油门)。缓冲的数据以及当前的数据将被写入一个测试文件中。(这使我们能够捕获测试开始前的数据,以免错过任何信息)。当车辆速度降至 0 或用户按下按钮停止采集时,软件将停止记录数据。用户可以立即切换到分析视图,在图表上可视化性能数据,显示诸如加速度、0到60英里加速时间、侧倾、制动距离等信息。GPS 数据点将允许绘制测试的路径,并检查与该点关联的数据。如果存在 OBDII 连接,发动机性能参数(油门位置、点火提前角、增压等)也将被记录。如果存在数据连接并且可以检索到天气状况,测试的日期、时间和地点以及当前的天气状况都将被记录下来。用户还可以为测试附加备注,以跟踪他们当时可能更改和测试的内容。
如果存在数据连接,用户将可以选择将性能数据保存到云存储。这可以是 Skydrive、Google Drive、Box 等。这样做的好处是,如果在性能测试期间超极本意外损坏(因为有人忘了把它固定好),数据仍然安全无恙,并可以加载回更换的超极本上!
应用的分析部分将在需要比较不同测试时发挥作用。通过选择和筛选要比较的先前测试,用户将能够掌握一次测试与下一次测试之间的性能增益或损失。在同一图表上叠加测试将使用户能够快速看到他们的调校努力在何处奏效。左右滑动切换图表将显示不同的参数比较,而双指张开将切换到四图表视图,允许用户同时查看他们选择的四个参数。
该应用程序不会向最终用户提供建议。数据的分析及其对相关车辆性能的意义将由用户自己决定。
另一个令人头疼的关键领域是 OBDII 系统及其在软件中的实现。我用过的其他应用虽然也提供了这些数据,但通常以一种不那么用户友好且相当晦涩的方式呈现。如果花些时间和心思,可以做得更好。然而,OBDII 连接及其协议相当复杂,因此对这方面的支持必须在应用程序中逐步发展。最初,该软件将支持读取标准的 OBDII 参数。有时,在调校车辆时,能够通过 OBDII 编辑汽车 ECM 中的值会很有帮助。商用扫描仪可以做到这一点,如果 OBDII 接口硬件支持,Rev Warrior 也应该能够做到。
较新的车辆还在 OBDII 连接器上使用 CAN 接口来连接车辆的 CAN 总线。大多数高级功能,如车身控制、ABS 等,都在 CAN 总线上,这是高端商用扫描仪的常见功能。只要 OBDII 硬件支持连接,Rev Warrior 也将支持从 CAN 总线读取这些参数和错误代码。这个功能可能需要一些时间,因为每个制造商都创建了自己的代码,而且几乎没有标准化。
关注点
在我看来,OBDII 连接是这个应用最有趣的部分。这很有趣,因为我最初担心的是加速度、陀螺仪和 GPS 传感。虽然枚举可用传感器并从中收集数据的过程仍然很有趣,但超极本形态中提供的这些功能已经消除了复杂性。现在,OBDII 连接才是关键所在。虽然加速度、距离和时间等物理性能数据都很重要,但性能调校师真正需要的是能够洞察 ECM 和发动机……了解在测试进行时车辆内部的情况。通过关联这些不同的数据方面,调校师可以精确地找出哪些改变能获得最大的性能提升。现代车辆的 ECM 提供了来自车载所有传感器(而且传感器数量众多!)的大量数据。收集、记录并提供这些数据以供使用,确实是充分发挥车辆性能的关键。幸运的是,一旦与 ECM 建立连接,识别可用的数据点然后请求这些数据并不困难。最终,要让 OBDII 部分工作,软件必须连接到接口设备,然后通过该设备连接到 ECM 并枚举可用的数据。很简单……对吧?
项目更新
2012年11月5日 - 在这个项目中,对我来说一个重要的功能是能够将性能数据保存到 Google Drive 或 Skydrive。我有一些空闲时间,开始研究应用的这两个方面。Skydrive 似乎有一个易于使用的 API,而且毫不意外地与 Windows 8 很好地集成。所以我决定稍后再回来看它。然后我把注意力转向了 Google Drive API。我发现 Google 有一个 .NET 组件库来帮助访问 Drive,但他们的文档不怎么样。示例只展示了一个非常基本的控制台应用,每次运行时都需要授权。这不是一个理想的情况,所以我开始四处寻找。断断续续花了4天的时间(大部分时间都在研究)才最终搞定。我把这个过程写成了一篇文章,在这里介绍如何在 WPF 中使用 Google Drive。那里的过程可以应用于其他 Google 服务,如 Tasks、Calendar 等。一旦你解决了身份验证问题,他们的库就使得使用这些服务变得轻而易举。但正是那个烦人的身份验证问题让人头疼。
最终应用 - 2012年12月3日
所以我确实完成了应用并及时提交参加了第二轮比赛,然而,在等待了8天之后,应用被拒绝了(稍后会详细说明),尽管我修复了问题并重新提交,但考虑到截止日期只剩3天,而他们第一次审核就花了8天,我并没有抱太大希望。我没有失望……现在是12月3日,距离评审截止日期已经过去两天,我的应用仍然没有被批准。我失望吗?当然……谁会不失望呢?但我要总结一下我做了什么以及学到了什么。也许将来能帮助到别人。
实际上,我对自己提交的应用程序非常满意。比赛的时间限制迫使我做出了一些牺牲。我甚至从我的日常工作中请了三天假,以便在截止日期前完成 Rev Warrior。最终,我不得不省略一些关键功能,特别是我想要的 Google Drive 和 SkyDrive 集成。我不得不砍掉这个功能。我想要更多的方式来分析捕获的数据并与之前的测试进行比较,我也只好砍掉这个功能,只提供了少数几个性能图表。我还想要 OBD II 连接功能,尽管在最初的提交版本中已经实现了,但在后续版本中我不得不把它砍掉。
触摸和手势
我还希望 UI 有 Windows Phone 中那种全景控件的感觉。我非常喜欢那种模式,因为它对用户来说非常直观,可以通过左右滑动来移动到应用的不同区域。在最初的设计中,我打算设置三个面板……一个用于检测传感器和捕获数据,一个用于分析数据,还有一个用于与 ECU(发动机控制单元……汽车的大脑)交互。由于 WinRT 中缺少串行支持,我被迫创建了一个 WPF 桌面应用。令我非常失望的是,WPF 中没有全景控件。有些人尝试复制它,但我发现它们不符合我的要求,或者在我的有限时间内使用起来太复杂。我最终使用了页面和过渡效果,并在每侧设置了按钮,用户可以触摸这些按钮在面板之间移动。我不太喜欢这个方案,但它能用。我学到的是,WPF 中的触摸和手势支持真的很缺乏。如果有人能做出一个好的全景控件,我会修复这个 UI,因为我对它现在的样子就是不满意。
我发现的另一件事是,WPF 控件为不同的驱动方式暴露了不同的事件。例如,一个小小的按钮就暴露了鼠标左键按下和抬起、鼠标右键按下和抬起、触摸按下和抬起、触控笔按下和抬起,以及键盘按下和抬起事件。当我在应用中需要判断用户是否按住录制按钮时,不得不挂钩所有这些事件,这真是个痛苦。如果能有像“按钮按下”和“按钮释放”这样的聚合事件就好了……我不在乎按钮是怎么被按下的,只在乎它被按下了。在一个支持触摸的世界里,尤其是在混合输入的 Windows 8 设备上,Click 事件和其他所有事件之间存在着一道鸿沟。顺便说一下……你必须在 XAML 或后台代码中使用这些事件的*预览*版本……否则你挂钩了事件处理程序却什么也不会发生。大概是因为 Click 事件先被触发,并将 Handled 标志设置为了 true。
用户界面设计
我必须把 UI 的功劳归于我的兄弟。他有艺术细胞,而我没有。他很慷慨地为我构思了设计。这是我实现之后他设计的截图:
请注意,这是我最初提交给英特尔的版本。你很快就会看到我最终提交(并且未能在截止日期前获得批准)的版本。我认为他的想法非常成功。这个想法是创造一种仪表盘的感觉,我觉得他真的做到了。所有的仪表都反映实时数据,直到你按住“启动”按钮来启动录制系统。当这种情况发生时,我解除了所有更新仪表的事件处理程序……基本上是“断开了它们的线路”。这样做的目的是为了不因处理不必要的 UI 事件而妨碍数据捕获。再说……驾驶员在进行性能测试时应该看着路……而不是超极本。
当测试结束,用户再次按下录制按钮停止数据采集时,事件会重新挂钩,系统会再次开始显示实时数据。如果用户按下左侧或右侧的按钮以切换到分析页面,程序会将仪表盘滑出,并将图表滑入。图表会根据捕获文件中的数据点数量自动缩放。
我想调整一下俯仰/偏航/滚转仪表,用一辆车来代替指针。有点像飞机控制面板里的虚拟地平线。我觉得那样能让那些仪表更清晰,所以会在后续版本中实现。
捕获数据
我最引以为豪的一件事就是数据捕获。如果你想一想,这其实是个不小的挑战。我需要能够以合理的捕获速率从任意数量的传感器中捕获数据,持续时间不定……同时还要让数据具有自描述性,以便能轻松导入到 Excel 或其他应用程序中进行后续处理和分析。另一个维度是,我需要将来自多个传感器的数据在时间上相互关联,并在输出到捕获文件时保持它们的顺序。
当谈到以一种可以自描述的方式存储数据时,我喜欢 XML,因为有 XMLSerialization 类。它们使得从文件中读写数据变得非常容易,因为它是一种非常便携的格式,并且它也很容易满足数据可以轻松导入 Excel 的要求。所以结果是一个可序列化的“传感器日志类”。这个类提供了三个公共成员:传感器名称、传感器数据类型,以及该传感器是否实际可用。还有两个公共成员返回传感器数据值。该类如下所示:
namespace RevWarrior.Models
{
/// <summary>
/// Provides the base class for a sensor that can be logged.
/// </summary>
abstract class SensorLoggingBase : INPCBaseClass, ISensorLogging
{
protected bool _logSensorData = true;
public event EventHandler DataChanged;
public abstract string SensorName { get; }
public abstract Type SensorDataType { get; }
public abstract bool SensorAvailable { get; }
public virtual bool LogSensorData
{
get
{
return _logSensorData;
}
set
{
if (_logSensorData != value)
{
_logSensorData = value;
NotifyPropertyChanged();
}
}
}
public abstract object GetSensorData();
public abstract SensorDataObject GetSensorDataSnapshot();
public virtual void OnDataChanged()
{
// Raise the DataChanged event...
EventHandler dataChangedEventHandler = this.DataChanged;
if (dataChangedEventHandler != null)
{
dataChangedEventHandler(this, new EventArgs());
}
}
public virtual double BoxNullableDouble(double? nullableDouble)
{
if (nullableDouble == null)
{
return 0;
}
return (double)nullableDouble;
}
}
}
INCPBaseClass
只是一个实现了 INotifyPropertyChanged
接口的类,提供了 INotifyPropertyChanged
的实现和支持代码。你可能会看到在 NotifyPropertyChanged
中我没有传递属性名。这是 .NET 4.5 的一个很棒的功能……有一个编译器宏可以帮你做到这一点。现在那个方法看起来像这样:
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
(这太棒了不是吗?再也不用传递和管理属性名了!)
在构建传感器类时,每个传感器日志对象都会被分配给一个传感器。如果传感器存在,该日志对象就会被添加到一个 Dictionary 集合中。当我试图将数据序列化到磁盘时,这成了一个问题……字典是不可序列化的……但我实际上找到了一个由 Dacris Software 发布的 SerializableDictionary
实现,它完全符合我的要求……(确切地说是`<Type T>`)……并解决了那个问题。(BCL 命名空间中有一个 SerializableDictionary
,但看起来支持可能不太稳定,所以我避开了它)
所以现在我有一个按传感器名称插入的传感器数据对象字典。这可以让我按顺序获取每个传感器并抓取当前读数。那么我该如何处理所有这些读数呢?在某个时间点,比如说抓取开始的第1秒,我从大约15个传感器中获取读数……我该怎么处理它们?答案实际上是将这个字典包装在一个类中,该类会添加一个时间戳,然后把这个整体放入一个链表中。结果就是一个由数据点组成的链表,每个数据点都有一个时间戳和一个数据点字典。链表非常好用,因为在末尾添加节点是一个非常快速的操作。我可以采集的数量将受限于系统内存。而且由于遍历链表非常容易,将列表写入磁盘也会非常简单。
结果非常棒。当我在比赛用的超极本上全速运行时,我得到了每秒5000个数据点的可观速度……也就是5kHz……而且这还是在 Visual Studio 中以调试模式运行的。这让我大吃一惊,也让我意识到我需要赶紧加一个计时器来减慢速度。我最终实现了一个动态的伪计时器,它允许用户设置一个采集周期,比如说每秒10个点,然后应用会开始计时每批传感器抓取所需的时间。实际时间和理想时间之间的差值被加载到一个 Thread.Join 操作的超时周期中,这个操作无论如何都在监视终止事件。结果就是我得到了一个既能等待理想的时间窗口又能等待线程终止事件的方法。它运行得非常完美,我可以根据需要将采样周期调整到最大值。
数据采集完成后,数据的链表会被传递给一个方法,该方法将数据写入磁盘。实际上,有两个链表。一个是缓冲区(总是在开头插入新节点),它记录了加速度传感器检测到运动之前的500个数据点。当达到加速度阈值时,数据采集线程会切换到记录链表,该链表会在末尾添加数据点,直到记录停止。在传递到磁盘之前,缓冲区链表会被反转到一个最终的运行列表中,然后记录列表会被追加到该列表的末尾。结果就是一个最终的、单一的链表,它代表了加速前的500个数据点以及加速后的所有数据点。这个列表被一次一条记录地写入磁盘,每条记录都包含一个时间戳和各个传感器的数据。最终生成的是一个XML文件,其中包含了运行期间采集的数据,可以直接导入到 Excel 中。
OBD II
其中一个关键功能是能够同时捕获 OBD II 数据,并将其与来自传感器的数据相关联。这使得 Rev Warrior 相比许多其他解决方案成为一个真正有用的工具。传统上,这必须通过昂贵的外部传感器包来完成,因为笔记本电脑没有内置传感器。这就是我认为超极本可以真正发挥作用的地方。能够拥有一台内置陀螺仪、加速度计、GPS 等设备的设备,并且可以将其与油门位置、速度、点火提前角等关联起来,将构成一个非常强大(且成本低得多)的组合。我仍然相信是这样,但在我重新提交时,我被迫向英特尔隐藏了 OBD II 功能。
为什么?因为英特尔的评估人员显然不理解“可选”硬件与“必需”硬件中的“可选”是什么意思。他们因为我没有提供测试应用程序所需的“必需”硬件而拒绝了我的应用提交。这有很好的理由。这个应用程序被编写成在没有 OBD II 连接的情况下可以优雅地回退。我自认为在这方面做得相当不错。仪表盘会变灰,并显示一条消息说硬件不存在。
此外,把硬件寄给英特尔也不现实。首先,比赛的时间不允许……他们第一次评估就花了8天……如果我把硬件寄给他们,时间会拖得更长吗?其次,硬件很贵。PLX Devices 的蓝牙适配器要100美元……我可没钱把它寄给他们然后就再也见不到了。再说,他们真的会把一台超极本插到某人的车上,看看适配器是否真的工作吗?那又怎么样?测试应用不是我的责任吗?如果 OBD 插上后实际不工作,他们有什么资格说三道四?他们的提交指南并没有规定应用必须符合我的想法或他们的想法!
解决方法很尴尬,我不得不向英特尔隐藏 OBD 支持。我无法移除那个库,因为它已经内置在应用里了,所以我只是简单地隐藏了仪表盘和那些让你进入硬件设置界面的按钮,然后告诉英特尔我已经移除了支持。这对我来说是个沉重的打击,因为我觉得这会是应用评审的关键……内部和外部传感的协同作用才是我真正想要展示的,用以说明超极本能做什么。但我觉得,有东西提交总比什么都没有要好,我希望如果我移除了有问题的功能,他们能及时批准应用。
(注意缺失的仪表盘……它们是由 OBD II 接口驱动的)
我完全打算继续开发这个应用并将其商业化。OBD II 功能会加回去,如果英特尔非要我寄一个适配器给他们,我会找一个更友好的应用商店来销售我的应用。
我还应该指出,我并没有重新发明 OBD II 的轮子。Channel 9 的优秀同仁们重新构想了一辆野马,并使用 OBD II 为其创建了一个非常酷的电子仪表盘。搜索“Project Detroit”可以查看并欣赏他们的作品。作为该项目的一部分,他们编写了一个很棒的 OBD II 库。真的,他们让我的项目在规定时间内成为可能,因为实际解码 OBD II 数据并不那么简单,他们帮我省去了很多这方面的开销。
然而,我发现他们的库是特定于福特 OBD II 连接的,我怀疑它甚至可能特定于福特产品线中的某些型号。Project Detroit 团队只实现了12种协议中的2种,所以当我把这个库连接到我的雪佛兰 Trailblazer 和我的别克 LaSabre 时,它就失效了。好的一面是,我现在对 OBD II 的了解比开始这个项目之前多得多,我想我能够修补这个库以支持所有12种协议。
Windows Professional 上的 WinRT
所以,在这个项目中我必须做的一件狡猾的小事是,弄清楚如何在桌面应用程序中使用 WinRT 堆栈。Device.Sensors 命名空间存在于 WinRT 堆栈中,尽管微软的文档说你*可以*在完整的桌面应用中使用 WinRT(至少是它的一个子集),但他们却懒得告诉你具体怎么做。谷歌救了我,但我必须说,这比它应该的难度大多了。我很容易就能想象到,有人的参赛作品会因此而受阻。找到正确的库和那个著名的(或者说臭名昭著的)*.winmd 文件,再加上知道如何卸载解决方案并使其仅支持 Win 8,这些都比应有的要令人沮丧得多。我可能会在这里写一篇文章,介绍如何让它工作,因为这方面的知识似乎真的存在一个真空地带。
经验教训
所以,我从这次比赛中学到了很多。负面的比正面的多,这很不幸。从好的方面来说,我确实强迫自己在大约6周的时间里,从一个空白的解决方案写出了一个可运行的应用。(注意我没说是完成的应用……)如前所述,我完全打算完成这个应用,并努力让它成为人们真正愿意购买的有吸引力的东西。作为这个项目的一部分,我研究了其他的解决方案,我的发现只会让我更加确信,我的应用在市场上有一席之地。挑战将是保持热情,并努力挤出时间继续开发和完善它。所以,尽管我很失望,因为审批流程 aparentemente 错过了评审,而且我对当前的版本也不满意,但我确实相信我有了一个可以继续构建的基础,这确实让我感到高兴。
Comodo
我发现我对 Comodo 并不满意。当我开始比赛时,我以为能免费获得一个签名证书会很棒。我感觉自己像是被诱骗,然后遭遇了货不对板。在尝试获取证书时,Comodo 并没有清楚说明要求是什么,或者流程是怎样的。唯一的选择是个人证书和公司证书。个人证书会包含我的地址和电话号码……这对几乎所有人来说都是不可接受的。你为什么要将这些信息发布在你发布的每一个应用上?所以唯一的选择就是公司证书。问题是,尽管我作为个体经营者工作了多年,但这对他们来说还不够。它必须是一个注册的公司。于是,我不情愿地花了125美元在俄亥俄州注册了一家有限责任公司,以公司名义开设了一个银行账户,并将所有文件提交给了 Comodo。那时他们告诉我,我需要一个在在线数据库中列出的有效电话号码。这在哪条要求里写着?幸运的是,我家里有一个基于 Asterisk 的电话系统,所以一条 PAYGO 电话线、一些脚本、提交到 SuperPages,24小时后我就有了一个“已列出”的电话号码。然后他们需要给我打电话……我开始怀疑这事儿到底有没有个头。幸运的是,我最终拿到了证书,但我很生气,为这么一件小事浪费了那么多时间和金钱……尤其是在我开始看其他公司的产品,发现他们的审批流程定义得更好,也容易得多的时候。
英特尔 AppUp
我曾对向英特尔 AppUp 商店提交应用感到非常兴奋。我很早就设置好了我的账户和仪表盘,并在开发应用时使用了他们的资源。他们的文档在我之前提到的 WinRT 问题以及其他几个我需要学习的关键领域都很有帮助。
然而,当涉及到提交过程时,我并不满意。在我提交应用的第二天,我意识到 MSI 文件中有一个 bug,导致应用安装后没有创建快捷方式。这很容易修复……但是没有办法更新我已经上传以供审批的二进制文件。我一上传它,就注定了失败,当时我甚至没有意识到。我的应用就那样被搁置着,直到他们真正开始审核,但这都无所谓了,我无法修改它,也无法修复那个我基本确定会导致失败的问题。而我猜对了……缺失的快捷方式是它第一次被拒绝的原因之一。我不明白为什么从我提交到他们实际审核之间的这段时间里,我不能去修改它。最终,这本可以节省他们的时间(不用审查一个我知道会失败的条目)和我的时间,以及我的参赛资格。但我对此并不感到怨恨……
当然,正如我之前提到的,硬件问题也是一个痛点。当应用程序首次启动时,它会询问用户正在使用哪种类型的 OBD II 硬件。第一个选项就是“无”。那么为什么英特尔认为硬件是程序运行所必需的呢?显然他们没有想清楚这个问题……如果运行应用*必须*需要硬件,那么我能理解测试人员手中有硬件是至关重要的。但是当应用在没有硬件的情况下也能正常运行时,他们凭什么因为没有硬件就拒绝这个应用呢?如果应用在连接硬件时无法运行,那真的是我的问题。他们到底是在批准这些应用上架销售,还是在调试和测试它们……如果是后者,他们就应该坦率地说清楚他们在做什么。
我和英特尔将会有第二轮较量……一旦我通过了这第二次提交,我就会把硬件支持重新加回应用中。正如我提到的,如果他们再因为可选硬件支持的问题来找我麻烦,我会去别的地方。(请注意,在提交表格上,你被问及*强制性*硬件……而 OBD II 适配器对我的应用来说不是强制性的……所以我没有列出它。)
另一件真正惹恼我的是 AppUp SDK。要将其集成到你的应用中,你需要包含库并添加一些代码。然而,一旦你这么做了,你就必须有一个监听代理来“伪造”对你应用的验证。当然,在调试时,你的应用 ID 必须是一长串的 1,但在构建发布版本时,它必须是你实际的应用 GUID。问题就在这里……那个真实的 GUID 在英特尔某个神秘的神明说它能用之前,是不能用的。所以我能实际安装和测试我提交给英特尔的应用吗?不能。因为根据监听代理的说法,我真实的 GUID 还不是“活动的”。这简直是太傻了……我在仪表盘里创建应用时就拿到了 GUID……为什么那个 GUID 不能在那时就生效?为什么应用必须发布后 GUID 才能用?这基本上迫使我盲目提交应用……不确定 SDK 集成是否真的有效。所以如果我为了与商店集成而将 AppUp SDK 添加到我的应用中,我必须使用那个虚拟 ID,然后在提交前记得改回来(不想因为忘记了像这样的小事而浪费一周时间),并且只能相信那些库在用真实 ID 启动时会正常工作而不会搞砸我的应用。再说一次,这完全是考虑不周的表现。
总的来说,我很高兴英特尔赞助了这次比赛,而且我得到了一个超极本,所以很难去批评他们。但与此同时,当你因为他们的流程不够灵活,或者因为他们误解了一个功能而被淘汰出局时,这真的很难接受。
比赛总览
我喜欢 Code Project 寻找赞助商并举办这些比赛。有时一些非常棒的东西会因为有激励因素(现金和奖品是很好的激励因素)而被挖掘出来,我认为这让比赛很有价值。
让我困扰的是,我在这场比赛中看到了与我参加诺基亚 Windows Phone 开发挑战赛时同样令我沮丧的事情。在这两种情况下,开发应用的时间都被严重压缩了。(诺基亚那次只有大约9个小时)比赛没有规定作品必须是原创、未发表的,也没有规定是否可以提交现有应用。所以对我来说很清楚的是,那些拥有现有应用,只是将其移植或修改以符合比赛参数的人,拥有明显不公平的优势。(我曾眼睁睁看着一个应用赢得了俄亥俄州哥伦布市的诺基亚挑战赛,那个人在演示中承认这是他公司的产品,他们已经开发了好几个月。他只是出现在那里,在诺基亚手机上做了一些编码和测试,就获得了获奖资格。与此同时,我坐在那里,为我辛辛苦苦连续干了9个小时的半成品感到尴尬。)这些人可能已经花了数月甚至数年的时间来完善他们的应用,然后看到一个机会,就把它扔进比赛里捞点金子。而我们这些(在我看来)遵守比赛精神的人,最终却要手忙脚乱地削减功能、跳过像测试这样的关键步骤,只为赶上截止日期提交点*东西*,因为有总比没有好。而实际上,我们根本没机会对抗那些精美的应用,因为我们的东西跟他们高度开发和完善的应用比起来,就像某个匆忙赶工的山寨货。所以就像诺基亚挑战赛结束时一样,我手里拿着一个半成品的尴尬之作,而那些比我领先了3年的人在领奖。我可能再也不会参加这样的比赛了,因为我感觉就像我在遵守规则从起跑线出发,而另一群人却从离终点线3英尺的地方开始……所以我根本不可能赢他们。
在这个过程中,另一件变得清晰的事情是,形势对个人/独立开发者非常不利……而且我认为在过去一年里,情况实际上变得更糟了,而不是更好。对应用商店、移动设备等的关注是件好事,而且有很多工具可以帮助你在这些领域起步,这也很棒。但是桌面开发已经退居次要地位,这让像我这样的单个开发者很难创造出成功的应用程序。举个例子:
- Visual Studio 有 Express 版本。太棒了……工具是免费的……但是等等,你很快就会遇到免费版的限制。作为 MSDN 订阅者,我有 VS Professional……但如果我没有呢?如果我不是因为我的正式工作而得到那个订阅呢?我理解微软希望通过不同的功能来区分他们的产品并推动不同的收入来源,但这各种版本只会将开发社区隔离开来,分成不同层次的“有产者”和“无产者”。
- 在 VS 2012 中移除安装项目是微软能做出的最令人震惊的打脸行为。当时我想,‘哦……没什么大不了的……我不怎么用它们。’但那是因为我的日常工作主要是在 Silverlight 中。当需要为提交打包我的应用程序时,我发现对于简单的部署,唯一可行的选择是 Install Shield 零碎版……你还得注册才能得到。这是一个功能被极度削弱的版本,缺乏像指定安装类型(最小、标准、自定义)和调整脚本甚至指定将创建哪种类型的安装程序等基本能力。而且如果你想使用任何被削弱的功能,就别指望去看那些好版本了。在美国,Express 版售价650美元……远远超出了任何独立开发软件的人的预算。情况更糟……想保持更新吗?那好,需要一个1500美元的维护计划。那人们怎么办?在 Visual Studio 2010 中创建解决方案,添加安装项目,然后在 VS 2012 中打开并工作,当需要打包部署时再回到 2010。简直是荒谬……
- 保护你的代码是市场上的另一个闹剧。Preemptive 会给你一个他们混淆器的评估版,但它的功能有限。有些保护总比没有好吗?也许吧……但即使在用评估版打乱了我的代码之后,我还是觉得它会在一个半月后回来告诉我它怀孕了。那么真正的代码保护要花多少钱?嗯,通常它会花你尤利西斯·格兰特不到5000美元,但如果你现在行动,通过他们针对单人开发者的特别营销优惠,你只需1250美元就能拥有它……但这是限时优惠。是啊……谢谢,但不用了……我还需要房子和给孩子们的食物。还有其他选择,比如 Eazfuscator.net,但它在去年夏天商业化了,400美元的价格对个人来说也相当昂贵。有一些开源项目,但还没有一个能达到标准。所以我的应用将以很少的保护进入应用商店,因为我没有钱去购买真正的代码混淆。
我理解所有这些公司都需要通过他们的产品赚钱。我自己也喜欢通过努力赚钱。但是,对于个人/小型独立开发者的关注度不够。这些工具对于能够负担得起成本的大公司来说是可用的,但我们其余这些在战壕里努力创新的人,却只能束手无策。这真是一种耻辱。所有这些工具公司都在谈论他们对开发社区的承诺,但这种承诺是有代价的……而这个代价的起点比我这样的人能够达到的地方高出好几层楼。
最终结论
所以我失望吗?当然了。我把我生命中的6个星期都投入到这场比赛中,结果却在门口被拒绝入场,就因为门卫不喜欢我袜子的颜色。这太糟糕了,没办法。我会在未来一段时间内对此耿耿于怀。唯一的积极方面是我得到了一台超极本(顺便说一句,它很棒),并且我有一个可以继续构建的应用,也许可以在公开市场上“获胜”。然而,我现在对编程挑战完全失去了兴趣,我想我再参加一次的可能性微乎其微。
欢迎在本文中发表您的评论和经历。您有类似的经历吗?我很想知道。
历史
2012年10月17日 - 初始版本
2012年11月5日 - 添加了关于 Google Drive 的更新,并链接到我写的关于在 WPF 中使用它的文章。
2012年12月3日 - 添加了最终项目笔记和吐槽。