17 Jan 2021

feedPlanet Maemo

Ubuntu Touch porting notes for the Redmi Note 7 Pro

In case you have a sense of deja-vu when reading this post, it's because indeed this is not the first time I try porting a device to Ubuntu Touch. The previous attempt, however, was with another phone model (and manufacturer), and did not have a happy ending. This time it went better, although the real ending is still far away; but at least I have something to celebrate.

The phone

I made myself a Christmas present and bought a Xiaomi Redmi Note 7 Pro, a dual-SIM phone from 2019 with 6GB of RAM and 128GB of flash storage. To be totally honest, I bought it by mistake: the phone I really wanted to buy is the Redmi Note 7 (without the "Pro"), because it's a modern phone that is working reasonable well with Ubuntu Touch. The online shop where I bought it from let me choose some options, including the RAM size, so I chose the maximum available (6GB) without being aware that this would mean that I would be buying the "Pro" device - the shop did not alter the item name, so I couldn't really know. Unfortunately, the two versions are two rather different beasts, powered by different SoC; both are produced by Qualcomm, so they are not that different, but it's enough to make the installation of Ubuntu Touch impossible.

But between the choice of retuning the phone to the shop and begin a new porting adventure, I stood firm and went for the latter. Hopefully I won't regret it (if everything goes bad, I can still use it with LineageOS, which runs perfectly on it).

Moreover, there already exist a port of Ubuntu Touch for this phone, which actually works reasonably well (I tried it briefly, and many things were working), but the author claims to be a novice and indeed did not follow the best git practices when working on the source code, so it's hard to understand what was changed and why. But if you are looking for a quick way to get Ubuntu Touch working on this phone, you are welcome to have a look at this Telegram channel.

What follows are the raw notes of my attempts. They are here so that search engines can index the error messages and the various logs, and hopefully help someone hitting similar errors on other devices to find his way out.

Getting Halium and the device source code

Installed the dependencies like in the first step. repo was not found in the Ubuntu 20.04 archives, but I had it installed anyway due to my work on a Yocto device.

Since my device has Android 9 on it, I went for Halium 9:

repo init -u git://github.com/Halium/android.git -b halium-9.0 --depth=1
repo sync -c -j 16

The official LineageOS repository for the Xiaomi Redmi Note 7 Pro is android_device_xiaomi_violet, but the page with the official build has been taken down (some DMCA violation, if you believe the forums) and no development has been happening since last year. A more active forum thread uses another repository which seems to be receiving more frequent updates, so I chose to base my port on that.

I actually tested that LineageOS image on my phone, and verified that all the hardware was working properly.

Initially, I created forks of the relevant repository under my own gitlab account, but then I though (especially looking at the Note 7 port) that creating a group just for this port would make people's life easier, because they wouldn't need to navigate through my 1000 personal projects to find what is relevant for this port. So, I created these forks:

Next, created the halium/devices/manifests/xiaomi_violet.xml file with this content:

<?xml version="1.0" encoding="UTF-8"?>
    <!-- Remotes -->
    <remote name="ubuntu-touch-xiaomi-violet"

    <!-- Device Tree -->
    <project path="device/xiaomi/violet"
             remote="ubuntu-touch-xiaomi-violet" />

    <!-- Kernel -->
    <project path="kernel/xiaomi/violet"
             remote="ubuntu-touch-xiaomi-violet" />

    <!-- Proprietary/Vendor blobs -->
    <project path="vendor/xiaomi/violet"
             remote="ubuntu-touch-xiaomi-violet" />

Fetching all the sources mentioned in the manifest:

./halium/devices/setup violet

Full output:

I: Configuring for device xiaomi_violet
Fetching projects: 100% (393/393), done.
hardware/qcom/audio-caf/apq8084: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8916: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8952: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8960: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8974: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8994: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8996: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/msm8998: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/sdm845: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio-caf/sm8150: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/audio/default: Shared project LineageOS/android_hardware_qcom_audio found, disabling pruning.
hardware/qcom/display: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/apq8084: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8916: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8952: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8960: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8974: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8994: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8996: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/msm8998: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/sdm845: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/display-caf/sm8150: Shared project LineageOS/android_hardware_qcom_display found, disabling pruning.
hardware/qcom/media: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/apq8084: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8916: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8952: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8960: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8974: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8994: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8996: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/msm8998: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/sdm845: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/qcom/media-caf/sm8150: Shared project LineageOS/android_hardware_qcom_media found, disabling pruning.
hardware/ril: Shared project LineageOS/android_hardware_ril found, disabling pruning.
hardware/ril-caf: Shared project LineageOS/android_hardware_ril found, disabling pruning.
hardware/qcom/wlan: Shared project LineageOS/android_hardware_qcom_wlan found, disabling pruning.
hardware/qcom/wlan-caf: Shared project LineageOS/android_hardware_qcom_wlan found, disabling pruning.
hardware/qcom/bt: Shared project LineageOS/android_hardware_qcom_bt found, disabling pruning.
hardware/qcom/bt-caf: Shared project LineageOS/android_hardware_qcom_bt found, disabling pruning.
Updating files: 100% (67031/67031), done.nel/testsUpdating files:  36% (24663/67031)
lineage/scripts/: discarding 1 commits
Updating files: 100% (1406/1406), done.ineageOS/android_vendor_qcom_opensource_thermal-engineUpdating files:  47% (666/1406)
Checking out projects: 100% (392/392), done.
I: Refreshing device vendor repository: device/xiaomi/violet
I: Processing proprietary blob file: device/xiaomi/violet/./proprietary-files.txt
I: Processing fstab file: device/xiaomi/violet/./rootdir/etc/fstab.qcom
I: Removing components relying on SettingsLib from: device/xiaomi/violet

Starting the build

Setting up the environment:

$ source build/envsetup.sh
including device/xiaomi/violet/vendorsetup.sh
including vendor/lineage/vendorsetup.sh

Running the breakfast command:

$ breakfast violet
including vendor/lineage/vendorsetup.sh
Trying dependencies-only mode on a non-existing device tree?

PRODUCT_SOONG_NAMESPACES= hardware/qcom/audio-caf/sm8150 hardware/qcom/display-caf/sm8150 hardware/qcom/media-caf/sm8150

Building the kernel

The configuration needs to be adapted for Halium. Locating the kernel config:

$ grep "TARGET_KERNEL_CONFIG" device/xiaomi/violet/BoardConfig.mk 
TARGET_KERNEL_CONFIG := vendor/violet-perf_defconfig

Getting the Mer checker tool and running it:

git clone https://github.com/mer-hybris/mer-kernel-check
cd mer-kernel-check
./mer_verify_kernel_config ../kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig

Prints lots of warnings, starting with:

WARNING: kernel version missing, some reports maybe misleading

To help the tool, we need to let him know the kernel version. It can be seen at the beginning of the kernel Makefile, located in ../kernel/xiaomi/violet/Makefile; in my case it was


So I edited the configuration file ../kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig and added this line at the beginning:

# Version 4.14.83

then ran the checker tool again. This time the output was a long list of kernel options that needed to be fixed, but as I went asking for some explanation in the Telegram channel for Ubuntu Touch porters, I was told that I could/should skip this test and instead use the check-kernel-config tool from Halium. I downloaded it, made it executable (chmod +x check-kernel-config) and ran it:

./check-kernel-config kernel/xiaomi/violet/arch/arm64/configs/vendor/violet-perf_defconfig
[...lots of red and green lines...]
Config file checked, found 288 errors that I did not fix.

I ran it again with the -w option, and it reportedly fixed 287 errors. Weird, does that mean that an error was still left? I ran the tool again (without -w), and it reported 2 errors. Ran it once more in write mode, and if fixed them. So, one might need to run it twice.

Next, added the line

BOARD_KERNEL_CMDLINE += console=tty0

in device/xiaomi/violet/BoardConfig.mk. One more thing that needs to be done before starting the build is fixing the mount points, so I opened device/xiaomi/violet/rootdir/etc/fstab.qcom and changed the type of the userdata partition from f2fs to ext4. There were no lines with the context option, so that was the only change I needed to do.

At this point, while browsing throught the documentation, I found a link to this page which contains some notes on Halium 9 porting, which are substantially different from the official porting guide in halium.org (which I was already told in Telegram to be obsolete in several points).

So, following the instructions from this new link I ran

hybris-patches/apply-patches.sh --mb

which completed successfully.

Then, continuing following the points from this page, I edited device/xiaomi/violet/lineage_violet.mk, commented out the lines

$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base_telephony.mk)
# ...
$(call inherit-product, vendor/lineage/config/common_full_phone.mk)

and replaced the first one with a similar line pointing to halium.mk. For the record, a find revealed that the SRC_TARGET_DIR variable in my case was build/make/target/. It contained also the halium.mk file, which was created by the hybris patches before. As for removing the Java dependencies, I cound't find any modules similar to those listed in this commit in any of the makefiles in my source tree, so I just started the build:

source build/envsetup.sh && breakfast violet
make halium-boot

This failed the first time with the compiler being killed (out of memory, most likely), but it succeeded on the second run. There was a suspicious warning, though:

drivers/input/touchscreen/Kconfig:1290:warning: multi-line strings not supported

And indeed my kernel/xiaomi/violet/drivers/input/touchscreen/Kconfig had this line:

source "drivers/input/touchscreen/ft8719_touch_f7b/Kconfig

(notice the unterminated string quote). I don't know if this had any impact on the build, but just to be on the safe side I added the missing quote and rebuilt.

Building the system image


make systemimage

failed pretty soon:

ninja: error: '/home/mardy/projects/port/halium/out/soong/host/linux-x86/framework/turbine.jar', needed by '/home/mardy/projects/port/halium/out/soong/.intermediates/libcore/core-oj/android_common/turbine/core-oj.jar', missing and no known rule to make it

The error is due to all the Java-related stuff that I should have disabled but couldn't find. So, I tried to have a look at the changes made on another xiaomi device (lavender, the Redmi note 7, which might not be that different, I thought) and started editing device/xiaomi/violet/device.mk and removing a couple of Android packages. Eventually the build proceeded, just to stop at a python error:

  File "build/make/tools/check_radio_versions.py", line 56
    print "*** Error opening \"%s.sha1\"; can't verify %s" % (fn, key)
SyntaxError: invalid syntax

Yes, it's the python3 vs python2 issue, since in my system python is python version 3. In order to fix it, I created a virtual environment:

virtualenv --python 2.7 ../python27  # adjust the path to your prefs
source ../python27/bin/activate

Remember that the second line must be run every time you'll need to setup the Halium build environment (that is, every time you run breakfast).

The build then proceeded for several minutes, until it failed due to some unresolved symbols:

prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/aarch64-linux-android/bin/ld.gold: error: /home/mardy/projects/port/halium/out/target/product/violet/obj/STATIC_LIBRARIES/lib_driver_cmd_qcwcn_intermediates/lib_driver_cmd_qcwcn.a: member at 7694 is not an ELF object
external/wpa_supplicant_8/hostapd/src/drivers/driver_nl80211.c:7936: error: undefined reference to 'wpa_driver_set_p2p_ps'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_set_ap_wps_p2p_ie'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_get_p2p_noa'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_set_p2p_noa'
/home/mardy/projects/port/halium/out/target/product/violet/obj/EXECUTABLES/hostapd_intermediates/src/drivers/driver_nl80211.o:driver_nl80211.c:wpa_driver_nl80211_ops: error: undefined reference to 'wpa_driver_nl80211_driver_cmd'

As people told me in the Telegram channel, this driver is not used since "our wpa_supplicant talks to kernel directly". OK, so I simply disabled the driver, copying again from the lavender Halium changes: commented out the BOARD_WLAN_DEVICE := qcwcn line (and all lines referring this variable) from device/xiaomi/violet/BoardConfig.mk and ran make systemimage again. This time, surprisingly, it all worked.

Try it out

I first tried to flash the kernel only. I rebooted into fastboot, and on my PC ran this:

fastboot flash boot halium-boot.img

I then rebooted my phone, but after showing the boot logo for a few seconds it would jump to the fastboot screen. Indeed, flashing the previous kernel would restore the normal boot, so there had to be something wrong with my own kernel.

While looking at what the problem could be, I noticed that in the lavender port the author did not modify the lineageos kernel config file in place, but instead created a new one and changed the BoardConfig.mk file to point to his new copy. Since it sounded like a good idea, I did the same and created kernel/xiaomi/violet/arch/arm64/configs/vendor/violet_halium_defconfig for the Halium changes. And then the line in the board config file became

TARGET_KERNEL_CONFIG := vendor/violet_halium_defconfig

I then continued investigating the boot issue, and I was told that it might have been due to an Android option, skip_initramfs, which is set by the bootloader and causes our Halium boot to fail. The fix is to just disable this option in the kernel, by editing init/initramfs.c and change the skip_initramfs_param function to always set the do_skip_initramfs variable to 0, rather than to 1. After doing this, the boot proceeded to show the Ubuntu splash screen with the five dots being lit, but it didn't proceed from there.

Setting up the udev rules

Even in this state, the device was detected by my host PC and these lines appeared in the system log:

kernel: usb 1-3: new high-speed USB device number 26 using xhci_hcd
kernel: usb 1-3: New USB device found, idVendor=0fce, idProduct=7169, bcdDevice= 4.14
kernel: usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
kernel: usb 1-3: Product: Unknown
kernel: usb 1-3: Manufacturer: GNU/Linux Device
kernel: usb 1-3: SerialNumber: GNU/Linux Device on usb0

Indeed, I guess the reason I could do this without even flashing my systemimage is because I had first flashed another UT system image from another porter. I'm not sure if I'd had the same results with my own image. Anyway, the USB networking was there, so I connected and ran the following commands to generate the udev rules:

ssh phablet@
# used 0000 as password
sudo -i
# same password again
cd /home/phablet
cat /var/lib/lxc/android/rootfs/ueventd*.rc /vendor/ueventd*.rc \
        | grep ^/dev \
        | sed -e 's/^\/dev\///' \
        | awk '{printf "ACTION==\"add\", KERNEL==\"%s\", OWNER=\"%s\", GROUP=\"%s\", MODE=\"%s\"\n",$1,$3,$4,$2}' \
        | sed -e 's/\r//' \

I then copied (with scp) this file to my host PC, and I moved it to device/xiaomi/violet/ubuntu/70-violet.rules (I had to create the ubuntu directory first). Then I edited the device/xiaomi/violet/device.mk file and added these lines at the end:

### Ubuntu Touch ###
### End Ubuntu Touch ###

It was now time to try my own system image. I rebooted my device into TWRP, I cloned the halium-install repository into my halium build dir, downloaded a rootfs for Halium9, and ran

./halium-install/halium-install -p ut \
    ~/Downloads/ubuntu-touch-android9-arm64.tar.gz \

The first time this failed because the simg2img tool was not installed. The second time it proceeded to create the image, asked me for a password for the phablet user (gave "0000") and pushed the image onto the device, into the /data/ partition. I then rebooted.

My first Ubuntu Touch image

Upon reboot, the usual splash screen appeared, followed by several seconds of black screen. It definitely didn't look right, but at least it proved that something had been flashed. After some more seconds, to my big surprise, the Ubuntu boot screen appeared, just with a smaller logo than how it used to be before, which also confimed that my system image was being used - in fact, I did not adjust the GRID_UNIT_PX variable before. Since this was an easy fix, I chose to focus on that, rather than fix the boot issues (indeed, my device did not move on from the Ubuntu boot screen). SSH was working.

I took the scaling.conf file from the lavender changes, put it in device/xiaomi/violet/ubuntu/ and added this line in the PRODUCT_COPY_FILES in device.mk:


I initially used system/ubuntu/etc/... as the target destination for the config file, like in the lavender commit, but this didn't work out for me. Then I changed the path to start with system/halium/, like it's mentioned in the ubports documentation, but it apparently had no effect either.

After a couple of days spent trying to understand why my files were not appearing under /etc, it turned out that the device was not using my system image at all: with halium-install I had my image installed in /userdata/system.img, while the correct path for Halium 9 devices is /userdata/android-rootfs.img. I was told that the option -s of halium-install would do the trick. Instead of re-running the script, I took the shortcut of renaming /userdata/system.img to /userdata/android-rootfs.img and after rebooting I could see that the Ubuntu logo was displayed at the correct size. And indeed my system image was being used.

So I started to debug why unity8 didn't start. The logs terminated with this line:

terminate called after throwing an instance of 'std::runtime_error'
  what():  org.freedesktop.DBus.Error.NoReply: Message recipient disconnected from message bus without replying
initctl: Event failed

It means, that unity8 did not handle correctly the situation where another D-Bus service crashed while handing a call from unity8. The problem now was how to figure out which service it was. I ran dbus-monitor and restarted unity8 (initctl start unity8), then examined the dbus logs; I saw the point where unity8 got disconnected from the bus, but before that point I didn't find any failed D-Bus calls. So it had to be the system bus. I did exactly the same steps, just this time after running dbus-monitor --system as root, I found the place where unity8 got disconnected, and found this D-bus error shortly before that:

method call time=1605676421.968667 sender=:1.306 -> destination=com.ubuntu.biometryd.Service serial=3 path=/default_device; interface=com.ubuntu.biometryd.Device; member=Identifier
method return time=1605676421.970222 sender=:1.283 -> destination=:1.306 serial=4 reply_serial=3
   object path "/default_device/identifier"
method call time=1605676421.974218 sender=:1.283 -> destination=org.freedesktop.DBus serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionAppArmorSecurityContext
   string ":1.306"
error time=1605676421.974278 sender=org.freedesktop.DBus -> destination=:1.283 error_name=org.freedesktop.DBus.Error.AppArmorSecurityContextUnknown reply_serial=6
   string "Could not determine security context for ':1.306'"
signal time=1605676421.989074 sender=org.freedesktop.DBus -> destination=:1.283 serial=6 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameLost
   string "com.ubuntu.biometryd.Service"
error time=1605676421.989302 sender=org.freedesktop.DBus -> destination=:1.306 error_name=org.freedesktop.DBus.Error.NoReply reply_serial=4
   string "Message recipient disconnected from message bus without replying"

So, it looks like unity8 (:1.306) made a request to biometryd, who asked the D-Bus daemon what was the AppArmor label of the caller, but since I didn't backport the D-Bus mediation patches for AppArmor, the label could not be resolved. biometryd decided to crash instead of properly handling the error, and so did unity8.

So I backported the AppArmor patches. I took them from the Canonical kernel repo, but they did not apply cleanly because they are meant to be applied on top of a pristine 4.14 branch, whereas the Android kernel had already some AppArmor security fixes backported from later releases. So I set and quickly inspected the contents of each patch, and found out that a couple of them had already been applied, and the last patch had to be applied as the first (yeah, it's hard to explain, but it all depends on other patches that Android has backported from newer kernels). Anyway, after rebuilding the kernel and reflashing it, my phone could finally boot to unity8!

Conclusion (of the first episode)

The actual porting, as I've been told, starts here. What has been documented here are only the very first steps of the bring-up; what awaits me now is to make all the hardware subsystems work properly, and this, according to people more experienced in porting, is the harder part.

So far, very few things work, to the point that it's faster to me to list the things that do work; it's safe to assume that all what is not listed here is not working:

  • Mir, with graphics and input: Unity8 starts and is usable
  • Camera: can take photos; video recording start but an error appears when the stop button is pressed
  • Flashlight
  • Fingerprint reader: surprisingly, this worked out of the box
  • Screen brightness (though it can be changed only manually)

For all the rest, please keep an eye on this blog: I'll write, when I make some progress!

0 Add to favourites0 Bury

17 Jan 2021 7:15pm GMT

17 Dec 2020

feedPlanet Maemo

Avast, Qt6 announcing new QPromise and QFuture APIs

Qt published its New_Features in Qt 6.0.

Some noteworthy items in their list:

I like to think I had my pirate-hook in it at least a little bit with QTBUG-61928.

I need to print this out and put it above my bed:
Thiago Macieira added a comment - 13 Jul '17 03:51
You're right
Philip Van Hoof added a comment - 13 Jul '17 07:32
Damn, and I was worried the entire morning that I had been ranting again.
Thiago Macieira added a comment - 13 Jul '17 16:06
oh, you were ranting. Doesn't mean you're wrong.
Thanks for prioritizing this Thiago.

0 Add to favourites0 Bury

17 Dec 2020 9:29pm GMT

06 Dec 2020

feedPlanet Maemo

How to generate random points on a sphere

This question often pops up, when you need a random direction vector to place things in 3D or you want to do a particle simulation.

We recall that a 3D unit-sphere (and hence a direction) is parametrized only by two variables; elevation \theta \in [0; \pi] and azimuth \varphi \in [0; 2\,\pi] which can be converted to Cartesian coordinates as

\begin{aligned} x &= \sin\theta \, \cos\varphi \\ y &= \sin\theta \, \sin\varphi \\ z &= \cos\theta \end{aligned}

If one takes the easy way and uniformly samples this parametrization in numpy like

phi = np.random.rand() * 2 * np.pi
theta = np.random.rand() * np.pi

One (i.e. you as you are reading this) ends with something like this:

While the 2D surface of polar coordinates uniformly sampled (left), we observe a bias of sampling density towards the poles when projecting to the Cartesian coordinates (right).
The issue is that the cos mapping of the elevation has an uneven step size in Cartesian space, as you can easily verify: cos^{'}(x) = sin(x).

The solution is to simply sample the elevation in the Cartesian space instead of the spherical space - i.e. sampling z \in [-1; 1]. From that we can get back to our elevation as \theta = \arccos z:

z = 1 - np.random.rand() * 2 # convert rand() range 0..1 to -1..1
theta = np.arccos(z)

As desired, this compensates the spherical coordinates such that we end up with uniform sampling in the Cartesian space:

Custom opening angle

If you want to further restrict the opening angle instead of sampling the full sphere you can also easily extend the above. Here, you must re-map the cos values from [1; -1] to [0; 2] as

cart_range = -np.cos(angle) + 1 # maximal range in cartesian coords
z = 1 - np.random.rand() * cart_range
theta = np.arccos(z)

Optimized computation

If you do not actually need the parameters \theta, \varphi, you can spare some trigonometric functions by using \sin \theta = \sqrt { 1 - z^2} as

\begin{aligned} x &= \sqrt { 1 - z^2} \, \cos\varphi \\ y &= \sqrt { 1 - z^2} \, \sin\varphi \end{aligned} 0 Add to favourites0 Bury

06 Dec 2020 1:12am GMT

12 Nov 2011

feedPlanet Linux-to-go

Paul 'pfalcon' Sokolovsky: Shopping for 3D TV...

Shopping for 3D TV (again), few findings:

12 Nov 2011 6:55pm GMT

Paul 'pfalcon' Sokolovsky: Hacking Luxeon SP-1

I finally going to get Arduino, and while I'm choosing flavor and waiting for it, I can't help but disassembling all devices I have at home, each time speaking: "This must have Arduino inside!" (meaning of course that I expect it to be based on general-purpose MCU). Gosh, I usually get "blob chip" (uncased chip with blob of epoxy on top).

Well, I finally had my expectations fulfilled - Luxeon SP-1 voltage stabilizer/cutter features ATMEGA48V-10PU (Flash: 4k, EEPROM: 256, RAM:512). Not only that, it is installed in DIP socket! Buy from Luxeon, they're hacker-friendly ;-).

I bought the device actually for a wattmeter it features (which fact is hard to figure out from common specs found in the shops, I accidentally read somebody mentioning it on a forum). The wattmeter is of course not bright - for a lamp rated 100W it shows 88W, and for more powerful equipment (like perforator) understates wattage even more (maybe it's difference between real and apparent power factor).

Still, for $17 you get Arudino-alike with voltage/current sensor and hacking possibility. Woot!

High-power board:

MCU board:

12 Nov 2011 5:58pm GMT

10 Nov 2011

feedPlanet Linux-to-go

Paul 'pfalcon' Sokolovsky: Links for November 2011


Linux kernel module tricks:

10 Nov 2011 3:21pm GMT

19 Oct 2011

feedPlanet OpenEZX

Antonio Ospite: Gnome 3: go to Shell? Not just yet, thanks.

In Debian Unstable the transition to Gnome 3 is taking place; when Gnome 3.0 firstly came out some unnamed geeky users complained loudly about the design decisions of the development team to push strongly towards gnome-shell as a new default UI; gnome-shell was designed focusing on usability (usability is a metric relative to a certain target audience BTW) and simplicity, hiding a lot of details from the users. Obviously you can never make everyone happy so some of us simply happened to be "out of target": you know us computer people (*cough cough*), we like to be in charge and control The Machine... I must admit I still don't have a definitive opinion about the gnome-shell concept, for now I just know that it does not suit me; I am going to try it eventually, maybe I'll get used to it, but in the mean time I need my desktop back just like I shaped it through the years; can this be done without loosing all the good Gnome technologies (Empathy over all of them)?

To be completely fair I have to say that there is little to complain about with Gnome developers, we can still get our good old GNOME desktop fully back by using the fall-back mode based on gnome-panel and live happily ever after, let's take a look at how this can be accomplished.

NOTE: GNOME people state that the fall-back mode is meant for systems with older graphic cards which cannot run gnome-shell, however it can very well be seen as a good opportunity for those who do not want to run gnome-shell just yet.

Getting back to the topic: some minor touches are needed to make the panel look more like what we are used to, maybe some of these settings could even become default for fall-back mode, we'll see.

First, enable fall-back mode (on Debian there is a dedicated session you can choose from the Log-in Manager for that) and change some desktop settings, in a terminal type:

$ gsettings set org.gnome.desktop.session session-name 'gnome-fallback'
$ gsettings set org.gnome.desktop.interface 'menus-have-icons' true
$ gsettings set org.gnome.desktop.interface 'buttons-have-icons' true
$ gsettings set org.gnome.desktop.background 'show-desktop-icons' true

gnome-tweak-tool can be used for some of these settings like shown in the attached images.

Then rearrange the applets on the panel as you please (use Alt-RightClick to access the panel properties), and fix the theming using this patch to have a light panel again (against gnome-themes-standard=3.0.2-1):

$ mkdir $HOME/.themes
$ cd $HOME/.themes
$ cp -r /usr/share/themes/Adwaita Adwaita-fallback
$ cd Adwaita-fallback
$ patch -p1 < $HOME/adwaita-fallback-panel-theme.patch
$ gsettings set org.gnome.desktop.interface 'gtk-theme' 'Adwaita-fallback'

Some final touches for the Metacity window manager and to the clock applet, and we are all set:

$ gconftool-2 --type string --set /apps/metacity/general/focus_mode mouse
$ gconftool-2 --type boolean --set /apps/metacity/general/compositing_manager true
$ gconftool-2 --type string --set /apps/panel3-applets/clock/custom_format '<span color="#333">%a %d %b</span> <b>%H:%M</b>'
$ gconftool-2 --type string --set /apps/panel3-applets/clock/format custom

Ah, in the new gnome-panel based on Gtk3 there are still some details to take care of, I hope issues like that will be addressed and that the panel will be supported for quite some time.

Attached images:
Gnome Shell default look on Debian
gnome-tweak-tool show desktop icons
Gnome 3 fall-back mode default look on Debian
Gnome 3 fall-back mode applets rearranged
Gnome 3 fall-back mode rethemed to have a light panel
Attached files:
text/x-diff iconAdwaita theme patch for fall-back mode

19 Oct 2011 9:37pm GMT

09 Jun 2011

feedPlanet OpenEZX

Michael Lauer: The Eagle Has Landed!

After letting us wait for a bit longer than scheduled (13 days), the hospital initiated the contractions. For the first couple of hours, everything went just perfect, but then the little one got stuck on the way and we had to resort to a cesarean section. Lara Marie Lauer was born 8th of June at 04:41 (AM) with 3460 gramms and 49 cm.

Mummy was still on intensive care and so they gave her to me. I can't express the feelings I had in this very moment. I'm still kind of overwhelmed every time I see her. Thanks for all of you who waited anxiously with me and those who prayed for us. The most important tasks for the near future is getting Mummy to recover and Lara Marie to become accustomed to us and the rest of the outside world.

Please bear with me if in the next time I'm not as responsive as usually :)

Lara Marie Lauer

09 Jun 2011 4:06pm GMT

30 May 2011

feedPlanet OpenEZX

Michael Lauer: German Post on time!

And now for something completely different… while we are all waiting for my baby to arrive (who was scheduled for 25th of May), she just received her first greeting card - together with a personalized bib and a towel (with integrated hood - pretty fancy!) from my good friends at #openmoko-cdevel.

Guys, seeing this card was very heartwarming - it means a lot to me that you share my anticipation, thanks a lot! And I'm 100% sure she will appreciate her gifts… now let's cross fingers it won't take much longer… waiting is the hardest part of it :)



30 May 2011 8:54am GMT