Wednesday, July 4, 2018

How not to: design and manage mobile applications. Eurosport Player example


I've been using Eurosport Player for years and can state that this is one of the most buggy and bad designed mobile application I ever seen.

Ok, I must admit it does not crash anymore, what it did in past frequently. It's updated regularly, though not necessarily to a better condition (for example, you can get additional context ads playing before every video in the updated version, whereas there were no such ads in the previous one - and they call this "critical update" ;-); apart from that they prefer to show bulcky selfish ads overriding important live actions, lasting for tens of minutes in a row, as though their directors went away). It does somehow work and present more or less content. But it is definitely not of the quality I expect for money.

First, the app demonstrates inconvenient and inconsistent UI design. Of course, they change UI from time to time in a cardinal way, in attempt to make it better, but actually making it worse. These changes themselves are very painful because you cannot find things on their usual places, and new control principles are not intuitive. I wonder: if they think every new design conforms to human usability, how every new design is drastically different to previous one? Do they suppose the human nature is changing with this frequency or do they rotate developers completely every month? Maybe they do not know themselves what they want (except for money they want constantly)?

The latest version at the time of writing is 6.1.6. Its general look and feel was introduced several months ago. From very beginning I got it, I'm encountering the following problems.

You can't read TV schedule in a familiar form. All is supposed to be interactive and reached through context search. But results are hard to interpret. Even if all filters are switched off, and it's supposed to show all sports, all channels - you can still get a screen without E1 or E2, which is nonsense, because E1 and E2 are showing something at every moment. It's important that you cannot switch on E1 or E2 in this situation. It's illustrated by the following screenshot:




Where is E2? Sometimes you can get nothing at all - neither E1 nor E2 current programs - and can only see stubs of Upcoming programs planned for later time.

This is a sporadic bug, which happens from time to time and vanishes itself after a while. Still this is very annoying because you can't switch to required channel at specific moment.

There is no a common timeline (exactly as a timeline, which was present in some previous versions, and allowed users to monitor many activities at once), no specific channel schedule (E1, E2), no special events broadcasting schedule in additional streams. Again, I mean a schedule with separated channels (such as videos from show courts on tennis tournaments) and time spans (when it starts, when it stops), and not a mosaic mess of splash images. And again, this feature was present in former times.

There is no way to read full text of titles of programs, because most of titles are truncated with ellipsis. This bug lives in Eurosport Player forever.

They don't know what is the full-screen mode. They do actually provide a button to switch it on, but their implementation leaves navigation bar on screen, so videos take only part of the space they could take.

There is no portrait screen orientation. I admit that video content is better displayed in landscape orientation, but Eurosport Player is not the only app on your device, and running it in parallel with something other requires you to rotate the device. Besides many UI forms in the player are free from videos, yet they are locked in landscape as well.

Ok, let us stop with UI problems and look at other things.

There is no way to check or manage your subscription from the app. You can only change email, password, name, and favourites. Or you can read app version, privacy policy, terms of use, and FAQ. Or you can finally do log out.

Here is the screenshot:



By the way, there is no option to start a new subscription right away - instead it will start only after 1 week of trial period (during which your card is not charged). This is inconvenient, because exchange rates can change, and you should actually monitor balance of the card until the week runs out. If it could be executed instantly, current balance and exchange rate would be known exactly, and the process finished in a blink - without more fuss. Even if this trial seems cool for someone, why not to provide an option to skip it, especially if this is not the very first time when subscription made? Probably Eurosport implies that a decent subscriber should have a sizeable credit on his/her card. But even so, I personally prefer, adhering to recommendations of Internet professionals, to use dedicated short-living virtual cards with specially allocated limited amounts, which allows for protecting yourself from modern security threads in e-commerce. If you find it's funny, please, find many stories from clients of big companies and banks, whose credit card data was stolen and exposed in past years. ;-)

In addition to the subscription topic: it's very inconvenient that in-app subscription is only allowed to be monthly:



Where is annual subscription, which is available from the site?

And finally, let’s address the problems related to the content.

Here is what you can see instead of a program:


This happens regularly while I'm in the same country, in the same provider network, so their FAQ does hit and miss in this case. Mostly it can be solved by the app restart.

Another one, similar but different:



This error happens even for 24-hours E1 and E2 channels! Again, the only way to get rid from the message is to kill the app and start it anew - only then you'll get the broadcasting videos.

Sometimes you can get nothing - a blank screen:



You can do nothing with this - just wait when Eurosport stuff awakes and fixes the problem, which is apparently on their servers.

Also I've got the following error several times on my Chromecast while subscription was active:


At those moments I was able to view programs on my tablet, yet TV was not an option. Since Chromecast+TV is preferred method of viewing sports for most users, when it stops working they don't actually get what they paid for. Sometimes the error can be dismissed by switching between different streams, but this does not help every time.  

Last but not the least. Probably this is most important, because it's not resolvable by client-side tricks. Special live streams from big events (such as show courts on tennis grand slams) stop and freeze constantly, while E1 and E2 run ok. Please note, this is not a problem with Internet, or user device, or something, since E1 and E2 works smoothly at the same moment. This looks like a problem with resources provisioning on Eurosport servers. They don't provide enough CPU, or memory, or bandwidth amounts, or compression class to ensure proper service quality on the additional streams. The additional streams are the main reason why I use Eurosport Player. With this problem the player is absurdly overpriced for one single channel E2 (in my case, I have E1 in my cable). And I tell you even more: the service becomes more and more expensive. For example, in 2017 I paid 15 in euro equivalent, and in 2018 it's already 30! 100% increase! For this 12 month euro exchange rate increased only by 9%.

I renewed my Eurosport Player subscription for the last time. If they don't improve (or give 91% discount ;-/), I'll leave.

If you know an alternative service for international sports broadcasting please let me know. If it's not exist, our last resort is free streams published by some altruists in the Internet. They are hard to find, they have their own drawbacks, but they do not pretend cool guys and do not beg for money for nothing.

PS. Eurosport support is not reachable. In response to my email to advertised support-com@eurosportplayer.com, I receive a short reply that the address is no longer in use. Sending emails to support@eurosportplayer.com, which is used as return address for payments confirmation, returns SMTP error:

550 Callout verification failed: 550 "support@eurosportplayer.com" is not a known user

You may also try to fill out a feedback form on their site as I did, but you'll hardly get a response.

Thursday, January 18, 2018

weborienteer.com is down

Unfortunately, the site weborienteer.com is not available anymore. It was hosted on OpenShift's free plan for years, but since OpenShift 3 was introduced, the service became very unstable and problematic. And even worse, yesterday I received a message from OpenShift with a postfactum statement that my "access has been removed due to a prolonged period of inactivity". All the data - the pod, the storage, the settings - have gone. This is just not true that there was a period of inactivy since the site was in use every day. So it's absolutely clear to me that RedHat just do not want to support and faithfully provide the new free plan (OpenShift Starter). It makes no sense to restore the site again and again, as far as they can kill it without a prior notice and with no reason.

I do not make money from weborienteer.com, so from very beginning it was and will be intentionally bound to free hosting. On the other hand, I don't want to use a free hosting populated with bulky ads. Until I find a replacement for spoiled OpenShift, the site is down.

Sorry for the inconvenience. This is not my fault. In the world where money rules - it's hard to maintain non-commercial, unpaid, altruistic projects.

Tuesday, November 14, 2017

OpenShift is getting worse

As you may know RedHat provides its own public cloud infrastructure - OpenShift - for years. It was a great service, available with paid and free plans. Many companies and developers used it both for production and testing.

Unfortunately, the situation has changed since OpenShift 2 has been replaced with OpenShift 3.

First, they decided to decrease number of instances (pods, in new Openshift 3 terminology) available in the free plan from 3 to 1. I admit, this is fair. The previous limit was incredibly generous, and allowed you to run a scalable (in its minimal form, yet fully functional) cluster with a load balancer for free. That was great, but could not last forever.

Second, they restricted the uptime of the single pod to a small value, which is not sufficient for uninterrupted operation.

Third, although this is a personal one, they made the web console less convenient and intutitive. Ok, I understand they wanted to make it more flexible, but somewhat streamlined workflow similar to version 2 would be a plus as an option.

Last, but not the least. As the system became more complicated, it's now less stable and reliable. Pods can easily stuck in any state (while starting or terminating), and as a result, your site becomes inaccessible for quite a long time, because the problems can not be resolved from the console and the support does not respond quickly. And even worse: they can deliberately switch off entire clusters for "maintenance" for several days in a row.

Monday, March 13, 2017

Hey, Google, I'm not a robot! Yet


Google was my favourite search engine for many years. Unfortunately, I have a ridiculous problem with Google from time to time. Instead of the searching interface I see now Google's captcha, asking a confirmation that I'm not a robot.

I do understand that Google receives a lot of requests from the world and from my IP specifically. My ISP is large enough to cover a half of my city, but there are cookies after all.

Most annoying thing is that the captcha seems buggy: it shows me pictures of storefronts, mountains, rivers, traffic signs, and numbers again and again, despite the fact that I mark relevant fragments every time. I really can distinguish things ;-). Nevertheless, Google's AI still thinks my clicks are somehow robotized. Or maybe Google tries to classify internet images to be indexed by forcing visitors to help? ;-) Or - no - my IP is in Russia - doesn't this mean that I'm a hacker by define? But a hacker is not a robot, anyway. I don't get it.

Well, I'm moving to other search engines. What a pity. What a shame.

P.S. After a further investigation I can say that your search request does matter. If I try something simple as a test, for example, "book" - it works, but if I enter more specific query - it fails with endless captchas. Of course, my queries are real world queries (nothing criminal, of course) and they are often banned.

Tuesday, November 29, 2016

Genesjs: a neat implementation of genealogy tree in pure HTML5/CSS3/JavaScript


As a new spare-time project I have just released small web-application. This is actually a single page intended for offline use. It provides a viewer functionality for interactive genealogy trees, and uses JavaScript or JSON file as a source of the actual data about your family. The number of supported types of graphs is minimal, but sufficient for the start. The diversity of personal fields and relations is not large as well. Yet on the other hand, the simplicity is a plus.

The idea behind the project was to provide a tool for building genealogy trees without a need to install a heavy application with long dependencies or register somewhere. Genesjs is a solely in-browser and standalone solution and solves all the problems.

If you think there is a typo in the name, then it's not. An application concerning your genesis and written in js should surely have name Genesjs ;-).

Here is some screeshots.







You can download version 1.0 here.

Bugs, suggestions? Feel free to contact me.

Thursday, September 22, 2016

Droidcon Moscow 2016


Today, on September 22-nd 2016, the 3-rd Droidcon conference was help in Moscow. This is a great opportunity for russian developers to get acquainted with latest Android trends and technologies, especially taking into account that Google I/O has its residence at other side of the Earth. ;-)

Of course Android 7.0 was presented as a new target for development, as well as many other topics, including usability, testing and even piracy on mobile market. Two sections were dedicated to VR and IoT. Although these terms are well established, and some products such as Google Cadrboard are very popular, they are seemingly still waiting for greater adoption and maturity. At least, I'm not impressed neither by next generation VR headset Daydream, nor by smartness and value of connected "things". The former looks too large for me and lacks natural human-computer interface (it still utilizes old plain extended manual control, obviously called "controller"), the latters are no more than toys at the moment (imho). I must admit that I did not see or test Daydream in real life, so my impressions are based solely on discrepancies between what I wanted and what I can get according to available information. Anyway, it's good to know about the work in progress, and I'm eagerly anticipating next releases.

Unfortunately this time there was no a hardware exhibition as a part of the event, so the only things that could be touched by hands and twiddled with came with speakers and were few.

Sunday, July 17, 2016

Smart glasses evolution is too slow

Back in 2014 I attended Android developer's conference in Moscow, and then published an overview here in the blog. One of the interesting things presented there was Epson smart glasses Moverio BT-200. Today, in 2016, Epson has announced the next generation of the smart glasses - Moverio BT-300 and started collecting pre-orders for it (unfortunately, only in US!).

I do not have the device yet, I only have read the specs. But here is my thoughts.

Most valuable improvement for me is HD display. The former one was too rude for eyes. The controller box is reduced in size, but it's still there, and I don't know why (read my first post for an explanation of my point of view). They added a camera, which is good, but the camera is only one, which is bad. It would be natural for such device to have 2 cameras for (1) streaming stereo vision from one device to another, (2) 3D recording, (3) 3D macro view and (4) 3D telescope view modes. I know they have stereo camera in their industrial smart headset. But I think this is a must have feature for home users as well.

To recap, they do evolve step by step, but I'd like to get smart glasses with more features, more light-weight and convenient. And I know it's doable on Android right now.

Friday, April 1, 2016

Space review for Snappy mobile browser

April 1-st. Google Play published apps reviews from space. Here is what they say about Snappy - an extendable browser for Android:

Tuesday, February 16, 2016

Snappy: mobile browser with Chrome-like extensions

I'm happy to announce a brand new product for Android - Snappy. This is a mobile browser which supports Chrome-like extensions.

The extendable browsers are standard de-facto on desktops. Yet mobile browsers provide very limited facilities for extension. Some of them declare a support of so called "plug-ins" or "add-ons", while the others withdraw such possibility completely due to supposedly large resource consumption that "plug-ins" would impose. Anyway, the range of features supported by extensions for desktop browsers is far wider than that's available for mobile browsers. This is why I decided to port a considerable part of Chrome extensions API to Android, using the mobile WebView based on the same Chromium project.

Today you may try it yourself. The browser is available in Google Play (Android 5+, WebView 48+ is highly recommended). Please visit the home page for further details. As the very first release, it may have some issues, but I hope that the whole idea is so powerful and universal to produce positive impression nevertheless.

Tuesday, January 12, 2016

Google thinks my tablet is a car

As an Android developer I often analyze system logs from my tablet. Starting from some recent updates (presumably, since Android 6.0) I see peculiar records there from time to time.

I/ActivityManager(591): Start proc 7994:com.google.android.gms:car/u0a21 for service com.google.android.gms/.car.CarService ... D/ChimeraCfgMgr(7994): Loading module com.google.android.gms.car from APK com.google.android.gms ... D/CAR.SERVICE(7994): Connecting to CarCallService... D/CAR.SERVICE(7994): com.google.android.projection.gearhead isn't installed. D/CAR.TEL.Service(7994): Creating a new CarCallService. W/ActivityManager(591): Unable to start service Intent { act=local_bind cmp=com.google.android.gms/.car.InCallServiceImpl } U=0: not found D/CAR.TEL.PhoneAdapter(7994): setListener: com.google.android.gms.car.dn@43460a D/NativeLibraryUtils(7994): Install completed successfully. count=14 extracted=0 D/CAR.TEL.Service(7994): Starting CarCallService with initial phone null ... D/CAR.SERVICE(7994): mConnectedToCar = false, abort E/ActivityThread(7994): Service com.google.android.gms.car.CarService has leaked ServiceConnection com.google.android.gms.car.hr@b3012b2 that was originally bound here E/ActivityThread(7994): android.app.ServiceConnectionLeaked: Service com.google.android.gms.car.CarService has leaked ServiceConnection com.google.android.gms.car.hr@b3012b2 that was originally bound here E/ActivityThread(7994): at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:1092) E/ActivityThread(7994): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986) E/ActivityThread(7994): at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303) E/ActivityThread(7994): at android.app.ContextImpl.bindService(ContextImpl.java:1286) E/ActivityThread(7994): at android.content.ContextWrapper.bindService(ContextWrapper.java:604) E/ActivityThread(7994): at android.content.ContextWrapper.bindService(ContextWrapper.java:604) E/ActivityThread(7994): at android.content.ContextWrapper.bindService(ContextWrapper.java:604) E/ActivityThread(7994): at com.google.android.gms.common.stats.g.a(SourceFile:128) E/ActivityThread(7994): at com.google.android.gms.common.stats.g.a(SourceFile:145) E/ActivityThread(7994): at com.google.android.gms.car.hc.(SourceFile:319) E/ActivityThread(7994): at com.google.android.gms.car.CarChimeraService.onCreate(SourceFile:74) E/ActivityThread(7994): at com.google.android.chimera.ServiceProxy.setImpl(SourceFile:115) E/ActivityThread(7994): at com.google.android.chimera.ServiceProxy.onCreate(SourceFile:105) E/ActivityThread(7994): at android.app.ActivityThread.handleCreateService(ActivityThread.java:2877) E/ActivityThread(7994): at android.app.ActivityThread.-wrap4(ActivityThread.java) E/ActivityThread(7994): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427) E/ActivityThread(7994): at android.os.Handler.dispatchMessage(Handler.java:102) E/ActivityThread(7994): at android.os.Looper.loop(Looper.java:148) E/ActivityThread(7994): at android.app.ActivityThread.main(ActivityThread.java:5417) E/ActivityThread(7994): at java.lang.reflect.Method.invoke(Native Method) E/ActivityThread(7994): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) E/ActivityThread(7994): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

What this means is that Android lives its own life, very far from reality, and tries to run tons of useless crap behind the scene, without user consent.

I don't have a car and my tablet has not ever been connected to one. Yet Google thinks it's acceptable to waste device's resources unconditionally and embed such ridiculous services into the system core. For example, the car service lives inside com.google.android.gms, which is a part of indispensable Google Play.

Monday, January 4, 2016

Chrome extension for secure, private, and faster Internet browsing

If you're reading this, you're definitely browsing Internet at the moment. Perhaps you spend a lot of time in the net. So am I. This is why it's important to know that we can surf the web securely, privately and fast. For this purpose I've made a browser extension which was originally developed for FireFox back in 2008, but then ported to Chrome. I've been using it for all these years and continue improving.

Not long ago the source code and downloadable crx-file have been moved from discontinued code.google.com to Bitbucket, where the latest version of Domain Cage is available.

You may say that there are a lot of analogous extensions and you'll be partially right. Yet Domain Cage has an optimal set of features: it's small, universal, standalone, customizable for your needs, and most importantly very restrictive by default - this helps you to keep privacy and security on unknown sites (what is very common situation in Internet). You may find further details in the introduction and the user guide.

Monday, December 14, 2015

Field research of Bluetooth Low Energy use for indoor positioning on Android

I've started investigations and practical tests of the modern Bluetooth Low Energy (BLE) technology applicability for indoor positioning tasks. This technology has been built with many useful applications in mind from very beginning, including IPS of course. The main question was if the technology is mature enough and widely adopted to provide real value.

You may perform a quick search on Internet and find numerous papers with academic research on the subject. I did it as well, and most interesting and thorough article was "An Analysis of the Accuracy of Bluetooth Low Energy for Indoor Positioning Applications" by R. Faragher and R. Harle. It mentions almost all Pros and Cons of BLE, and provides practical results of a comparison between WiFi- and BLE-based positioning approaches. Most important conclusions that I made for myself after the reading are:

  • a special non-connectable BLE devices are preferred for building IPS infrastructures because of their continuous discovery (connectable devices are reported only once per each scan request); as far as specific building environment may not comply with this requirement, a mobile application should explicitly repeat BLE scans in a loop, which may lead to additional resource consumption and occasional hangs (find more details below);
  • BLE signal range is shorter than WiFi's one, and RSSI level of the same beacon may change significantly as a result of ad hoc switching between 3 frequency bands used by BLE internally (it can be a problem to sort out measurements by BLE channel using provided mobile APIs); thus, a special fingerprinting algorithm should be used with an emphasis on specific beacon existence instead of its RSSI, or deep smoothing should be applied, making processed RSSI values more inertial;
  • a single BLE scan should be performed at least once at a second in order to provide 1-2 meter positioning accuracy; unfortunately this parameter can be hardly manageable and limited by hardware implementation specific to every manufacturer;
  • according to the article, BLE scanning is negatively affected by enabled WiFi receiver, so for better results BLE should be used while WiFi is disabled, which may not be feasible for all use cases;
  • for best result at least 5-6 beacons should be detectable in every spatial point; combining the fact with the fast decay of BLE signals one can deduce that a high density of beacons is required for good positioning performance;

Just as illustration of the issues mentioned in the 1-st and 3-rd points, here is a related discussion on the StackOverflow. To recap: BLE implementations may vary significantly between Android versions. This makes it difficult to build an application with consistent BLE behaviour on all variety of Android market, supporting BLE at the moment (70% of Android devices).

I added BLE scanning and fingerprinting in a test version of WiFiLine. One additional observation is that BLE is not yet widely used in local stores here in Moscow. Actually the number of BLE devices is 10-100 times less than WiFi hotspots. My thought is that BLE is not yet ready enough for efficient public use.

If you think you know a place with good BLE coverage and you're ready to play with the experimental version of WiFiLine, please, let me know and I'll send it to you.

Sunday, April 26, 2015

OFF: how Google makes Android worse

Some days ago I got OTA update with Android 5.1. This version does probably improve something, but it apparently impairs other things as well. And because it's related to the system carousel - the list of running applications (on the so called "recents" screen) - which has bad design from the very beginning of Android 5, I couldn't help but writing about this miserable part of UI.

First, I must say that the carousel is constantly changing from one Android version to another between horizontal and vertical layout, as though Google's developers are uncertain themselves which variant is appropriate. The carousel is used intensively, so even a little flaw in its design brings big problems. I'm currently speaking about standard Android in general, and standard Android 5 in particular. Other customized firmware may be free of the issues I'm going to describe.

In Android 5, the carousel is always vertical on my pad. Well, it could be appropriate for portrait screen orientation, but the carousel remains vertical even in landscape mode. When you try to flip through the apps from bottom to top, you will constantly activate the central button of the navigation bar, floating in foreground (over the carousel!), especially because the button has an enlarged sweetspot, because it's Google button (it invokes "Google App" including quicksearchbox and other stuff). It took me a long time to get accustomed to the new - not so convenient - practice: in order to swipe apps from bottom to top, one should swipe from center! Otherwise you'll get into the Google app.

That's how it was since Android 5.0. In Android 5.1 they introduce new strange bug in the carousel. It does not work when you tap an app in it first time. After the first tap the carousel is closed and the launcher is shown. Only if you open the carousel second time, it works as expected.

I know, this is far from the main subject of the blog, but at last it's all about Android. And I'd prefer that Android would not prevent me from working with my applications.

Monday, March 16, 2015

WiFiLine's synthetic probability algorithm revealed

As I promised, I'm posting a short explanation of the built-in "synthetic probability" location algorithm. To start with it let us consider how WiFi data looks like. When you scan a building you get a list of geographical points with WiFi measurements, each of them contains signals from several hotspots, and every hotspot signal is normally detected many times demonstrating varying levels - so called RSSI (Received Signal Strength Indication). All this data is stored in the map, and can be viewed - just switch to the "Scan and Edit" mode, open the list of points and expand any of them - you'll see the names of hotspots detected in this point. Tap a hotspot to open a dialog presenting this spot's RSSI distribution.

Usually it's bumpy, but the more scans you perform in a point the more smooth distribution you get. According to the Central Limit Theorem the distribution tends to be Normal (Gaussian), so one can estimate its mean and standard deviation. This is where the word "synthetic" in the algorithm name comes from: it implies that we can build a synthetic (near to real, yet artificial) probability distribution (mass) function from acquired WiFi data.

Of course, this is just a probability of getting specific signal level of a hotspot S in a point X. We need to combine all such probabilities somehow in order to calculate current user location. And here is the Bayes theorem comes in handy.

P(A | B) * P(B) = P(B | A) * P(A), where

  • P(A) and P(B) are the probabilities (priors) of A and B independent of each other;
  • P(A | B) is the conditional probability of A given that B is true;
  • P(B | A) is the conditional probability of B given that A is true;
Now let us add some suffixes to bring it into our context:

P(Asi | Bxj) * P(Bxj) = P(Bxj | Asi) * P(Asi), where

suffixes 'si' and 'xj' stand for i-th hotspot and j-th point respectively, so:

  • P(Asi) is the prior probability of i-th hotspot;
  • P(Asi | Bxj) is the conditional probability of observing i-th hotspot in j-th point;
  • P(Bxj) is the prior probability of j-th point;
  • P(Bxj | Asi) is the conditional probability of being in j-th point provided that i-th hotspot signal is detected;
Apparently, it's the last probability which we are after:

P(Bxj | Asi) = P(Asi | Bxj) * P(Bxj) / P(Asi)

In the right side of the equation, P(Asi) can be estimated as a percentage of points where the hotspot Si was detected. P(Bxj) is initially 1/N for every point, where N is the total number of points, but later it can be refined by applying our knowledge about current user location and reducing N to a reasonable neighbourhood. At last P(Asi | Bxj) is the probability obtained from the synthesized probability distribution of signals described above.

Having P(Bxj | Asi) for different i-s in every point j, we should combine them by hotspots (by i) in order to get the total probability of point Xj. According to the formula of mutually non-exclusive events:

P(Xj) = P(Σi(Bxj | Asi)) = 1 - Πi(1 - P(Bxj | Asi))

The point with largest value (or an average of K points with largerst values) is most likely the current location of the user.

This is a simplified description of the "synthetic probability" algorithm. It does not cover many nuances such as signal level calibration and in-motion scanning but gives you an idea of how WiFiLine works behind the scenes.

Friday, March 6, 2015

New WiFiLine version has been released

New version of WiFiLine - 1.1.3 - has been just released. The main changes are:

  • debug marks with current user position(s) detected by all built-in algorithms are now optional and disabled by default; in order to enable the marks, one should enter "debug:on" in the processing command line (described some time ago in the blog); "debug:off" disables the marks;
  • the naive multiplier algorithm has been changed a bit, but it's still an experimental thing;
According to latest tests in fields, recommended methods are extended fingerprint and synthetic probability again, as they were before. Position accuracy is 10 meters. I plan to shed some light on the probabilistic method in a future. As for neural network, it requires manual finetuning of input data to get best results. For example, it could be worth removing some non-discriminative hotspots from the map.

Готовится новый выпуск WiFiLine

В разработке и тестировании находится следующая версия WiFiLine. Вот основные изменения:

  • Отладочный вывод на карту меток с результатами работы всех алгоритмов позиционирования сделан опциональным; по-умолчанию, он отключен; чтобы его включить, необходимо ввести в командной строке "debug:on";
  • слегка изменен алгоритм naive multiplier, он все еще является экспериментальным;
По итогам полевого тестирования, рекомендуемыми по-прежнему являются методы расширенного отпечатка и синтетической вероятности. Точность позиционирования - 10 метров. В одной из следующих публикаций я расскажу более подробно о вероятностном методе. Что же касается нейронной сети, то для получения с ней хороших результатов, требуется тонкая ручная подготовка исходных данных, в частности, удаление некоторых хотспотов с малоинформативными сигналами из карты.

Sunday, February 22, 2015

ОФФ: коллективное гипертекстовое литературное творчество

Не так давно я опубликовал один свой проект, никак не связанный с темой навигации, и чтобы не заводить отдельный блог по нему, решил дать краткий анонс здесь - все-таки автор один и тот же. Проект был начат много лет назад и, что называется, "лежал под сукном".

Это веб-сервис для коллективного гипертекстового литературного творчества. Если кратко, то он предназначен для коллективного написания и чтения гипертекстовых произведений с разветвленными альтернативными сюжетами, динамическим перестроением персональной версии произведения по запросу пользователя, и голосованиями по любому фрагменту, по результатам которых на лету получается наиболее популярная версия.

В отличие от систем класса wiki, единицей редактирования является не статья, а предложение (фрагмент). Выбор последовательности предложений осуществляется подсчетом их голосов (версия сообщества) или пользователем (персональная версия), а не путем долгих обсуждений каждой правки на отдельной странице.

Сам сервис расположен по адресу hyperfiction-orienteer.rhcloud.com, а более подробное описание - на отдельной странице. Но одна картинка, как известно, стоит сотни слов, поэтому вот краткая презентация:

Каковы общие тенденции рынка в этом направлении? И в печатной литературе, и в электронной форме имеется много произведений с коллективным авторством. Также в интернете выложены многочисленные гипертекстовые произведения, в которых можно менять поток чтения с помощью переходов по гиперссылкам. Интерес к подобным экспериментам находится на подъеме. Интернет, проникший во все сферы жизни, подсказывает пути развития литературы в сторону её социализации (использование социальных сетей) и проактивного отношения к сюжету. Имеются многочисленные примеры форумных ролевых игр, принцип которых заключается в пошаговом описании каждым пользователем действий своего героя в ответ на описания действий героев других пользователей. Известны случаи написания произведений в виде постов в социальных сетях, включая Твиттер. В общем, существует тенденция "интернетизации" литературных форм, что включает коллективное творчество, публичную оценку, многовариантность мнений, интерактивность.

В чем слабые места вышеназванных конкурирующих инструментов? Форумным ролевым играм мешает в развитии использование неприспособленных под их специфику форумных движков. Статическим гипертекстовым произведениям не хватает интерактивности и гибкости. Закрытые коллективы авторов не позволяют пользователям самим принимать участие в творчестве и влиять на произведение хотя бы в виде оценки фрагментов. Все элементы предлагаются разрозненно, и полноценной системы для коллективного, интерактивного, многовариантного создания произведений не существует. Ну или не существовало.

Данный проект - одно из возможных решений.

Wednesday, February 4, 2015

New map visualization feature is available in version 1.1.2

New version 1.1.2 of WiFiLine has been just released. It introduces new map visualization. In the Location mode, a map can now automatically rotate according to user's "view" direction. This makes it easier for user to take his or her bearing, but may create some difficulties in reading labels on the map.

New feature can be enabled in the context menu of the main screen. By default it's disabled, and maps are shown in the standard way: floorplan is static, and user's current bearing is indicated by a green sector inside the compass. When the feature is enabled, there is no a green sector in the compass, because user's "viewing direction" is always forward (up on the screen), and the compass shows only blue and red sectors for the North and the South.

The rotation of a map is performed around the point of user's current location. If current location is unknown (which is possible if navigation was not started, or the algorithm failed due to incomplete or irrelevant WiFi data), map remains static in its default orientation.

In other modes - Scan and Edit, Hotspot signals - the new visualization made intentionally unavailable, otherwise it would be hard for user to edit and analyze the map.

Режим отображения карты с изменяющимся азимутом

Для следующей версии WiFiLine готовится новый способ отображения карты в режиме навигации. В нем карта постоянно поворачивается в соответствии с текущим направлением "взгляда" пользователя. Это позволяет проще ориентироваться на местности, однако может затруднить чтение надписей на карте.

Режим переключается из контекстного меню главного экрана. По-умолчанию он выключен, и поведение карты аналогично прежним версиям программы, то есть отображение плана статично, а текущее направление "взгляда" пользователя обозначается подвижным зеленым сегментом в компасе. Если новый режим включен, карта будет целиком поворачиваться синхронно с поворотом пользователя на местности, а компас отображается без зеленого сегмента (только синий и красный сегменты с направлениями на север и юг), поскольку "взгляд" всегда направлен вперед (вверх экрана).

Следует отметить, что автоматический поворот карты производится относительно последнего определенного местоположения пользователя, поэтому если точка еще не найдена (например, если навигация вовсе не запускалась или определить местоположение просто не удалось), карта остается статичной.

В режиме редактирования и анализа WiFi сигналов данный способ ориентации недоступен, чтобы не осложнять пользователю работу с функциями редактирования.

Thursday, January 22, 2015

Processing commands for WiFi maps

In the previous post I have started a story about built-in processing commands for WiFi maps. But the story came out too long for a single post, so I have only managed to cover the starting phase: how to open the command line and how does it look like. Today I'll describe the commands themselves. You can enter several commands in a row delimiting them by spaces. The commands will be executed in the same order as they occur in the editbox.

  • clear:name - clears names of all points
  • clear:neighbors - clears all neighbors (links between points); can be useful after attempt to generate neighbors with inappropriate neighborhood radius
  • clear:signals - clears detailed WiFi measurements (scans) stored in points, but leaves information about detected hotspots and their average signal levels in each point - this may help to shrink map size but prevents probabilistic location algorithm from functioning
  • lineup:IDs-IDe - aligns a series of successive points with identificators IDs-IDe to the starting point IDs; IDs can be larger than IDe or vice versa; alignment is performed in direction with longest distance between points IDs and IDe, for example, if delta in X coordinate is 1000 and delta in Y coordinate is 100 the points will be aligned in a horizontal line with Y equal to Y of the starting point IDs and preserved X coordinates
  • stretch:IDs-IDe-PERCENTS - expands or squeezes a series of points in direction from IDs to IDe; again IDs can be larger than IDe or vice versa; the PERCENTS is the added fraction of initial distance between the starting point and every other point till the point IDe; for example, if PERCENTS is 10, all points will be moved by 1/10 part of their corresponent distances from IDs; both X and Y directions will be affected
  • shift:IDs-IDe-DX-DY - shifts the points from IDs to IDe by the specified number of image logical pixels in X and Y axes correspondingly
Here is the example of processing command executed on the Kaleidoscope map:

clear:name lineup:1-116 lineup:117-221 lineup:478-462 lineup:435-461 lineup:479-499 lineup:412-434 lineup:385-411 lineup:355-384 stretch:479-499-12 shift:550-575-5-0

The same commands can be executed automatically during XML-map loading. For this purpose a new XML-tag was added to the map specification: preprocess. The tag is optional. The map header example:

<place xmlns="http://weborienteer.com/wifiline">
  <desc>
    <header>
      <id>RU.MM.SZAO.KA</id>
      <name>Kaleidoscope Shopping Center</name>
      <date>2015-01-10 10:10:10</date>
      <coordinates longitude="37.4446" latitude="55.850567" />
      <format>1.2</format>
      <images default="1" scale="85">
        <image floor="1" svgfile="k1.svg" azimuth="155.0"></image>
      </images>
      <preprocess>clear:name lineup:1-116 lineup:117-221 lineup:478-462 lineup:435-461 lineup:479-499 lineup:412-434 lineup:385-411 lineup:355-384 stretch:479-499-12 shift:550-575-5-0</preprocess>
    </header>
  </desc>
  ...
This new feature will hopefully help to refine WiFiLine maps and make them good looking.