Open WouterJD opened 4 years ago
@m472 I see that cadence = 0 in the logfile. This may be due to lose contact/no magnet etc. Tacx Fortius does not work well when there is no cadence.
So current status for the i-Genius development is that it conceptually works, but is not yet stable for @m472 ? Correct?
@mikeymclellan the "old" tacx trainers are not very precise nor repeatable in the power-reporting. It's also quite dependant of the tire-temperature. My yesterday's training was tenths of Watts off (realized versus requested power) but after half an hour is stabilized. This has to do with the calibration, which obviously moves during the training. I already experimented with a dynamic calibration (realized power must be equal to requested power) but did not activate it in the software because it seemed superfluous; where yesterday I had differences again. Yesterday the room was colder than some time ago ==> colder tire ==> longer warming-up time.
@m472 @mikeymclellan could you share the current status of the code modifications you made, please?
@WouterJD Thank you for the hint with the cadence, I have not had any problems with the slope simulation if the cadence was measured correctly.
So current status for the i-Genius development is that it conceptually works, but is not yet stable for @m472 ? Correct?
Yes, I would agree. It works well if it works but I have the following issues with the code:
TacxMode
parameter in SendToTrainer
: is Tacx-Mode == stop
needed for the Genius or not?
I think for my setup it would not need to be used, but I don't know about the head unit.TargetPowerToResistance
needed and if so, should SendToTrainer
always send a grade instead of a power target?
I first had it implemented like that but ERG mode works better in Zwift if I send target power instead (see latest commit: https://github.com/m472/FortiusANT/commit/e3a0c2658585d1bee6467dfb96d49d4882ecc017).clsAntTacxVortexTrainer
Should I create a pull request to try to integrate the code or continue testing and try to find out how to implement the head unit stuff correctly (probably implement according to reverse engineered Bushido protocol and see if it works with @mikeymclellan)?
hi @m472 for a starter I do not know how the Genius works, so it's difficult to answer questions on technical level. A quick reaction now to assist to forward, I would need more time for an in-depth verification.
Tacx-Mode == stop
perhaps leave as is; merely needed for dongles that disconnect I think.
def TargetPower2Resistance(self):
self.TargetResistance = self.TargetPower
If the Genius supports setting TargetPower or TargetGrade, that must be implemented From what I understand is that the Vortex supports setting TargetPower only (at least: that is what is implemented)
I do not have Genius specs, so cannot help you here
Pull request: It's most usefull that you submit the pull-request when the implementation is fine for you.
If you want me to do code-review in the meantime; yes submit it.
Success guys! Keep me posted.
- As I don't have the head unit for the Genius, I am not quite sure what to do with the head unit code I copied from
clsAntTacxVortexTrainer
The i-Vortex consists of two devices; the brake and the headunit. Your system works without the headunit, so the thing is "only" to provide buttons and manual control.
You could choose:
In clsTacxAntGeniusTrainer
In FortiusAntBody.py I would also leave the headunit code present
I do not know how you implemented the Genius channel info; did you add new variables or simply change the Vortex variables?
You could choose:
- implement brake-only
- implement brake and head-unit , but leave head-unit untested.
Decided to go for the second. Actually the button protocol of the Bushido and the Vortex is the same, so I guess its probably the same for the Genius as well.
In clsTacxAntGeniusTrainer
- (pairing can take a minute) will remain visible since you do not have a head-unit, which is not nice. I think I would add a flag to ignore absense of head-unit and leave code complete (to be prepared for later extension).
I added a flag to the __init__
method and the --no-headunit
flag to the command line arguments.
I do not know how you implemented the Genius channel info; did you add new variables or simply change the Vortex variables?
I guess you mean the variables DeviceTypeID_VTX
, RfFrequency_2466Mhz
etc. I did create new variables for these in order not to affect the Vortex functionality
This is amazing work people! I have now been testing the new additions made by m472 and by gosh it works! I have successfully been using my non-smart Genius with Golden Cheetah.
I have a head unit; is there a way I can help you test the code out for that? So far it is not seeming to recognise the head unit.
Also is there a calibration routine Genius users can use reliably now that we are free of TTS4? Ideally the wheel should be spun up to 30km/h for about 6-7 minutes in my experience with TTS4. I think the heating of the tyre changes the resistance or something.
The title is changed to be consistent with the other developments Related issues: #46 = Vortex, #101 = Genius, #117=Bushido
I have a head unit; is there a way I can help you test the code out for that? So far it is not seeming to recognise the head unit.
Yes you sure could. First question: are you able to program in python?
Sorry Wouter, I am not able to program in Python (or anything else properly - I am very limited to just trying to change a few numbers here and there!). I just have the hardware ready to test it out and provide some logs.
@Sigfreid74 as I read in @m472 response, disabling the headunit is a command-line option. So it appears ready to test
@m472 great work and I also see @Sigfreid74 's confirmation!
Now we can proceed with details and integration!
I added a flag to the
__init__
method and the--no-headunit
flag to the command line arguments.
Would it be an idea to define
-t Genius
or
-t Genius-
in stead of a separate command-line parameter?
A similar option could be usefull for the Vortex (Vortex- for no headunit). It will be obvious that such configurations exist.
I will look into the Genius code in detail lateron (now busy with bluetooth, then genius). What is you opinion on the Vortex / Genius classes; integrate or keep separate?
As permissible values for -t we will have Vortex, Genius, Bushido (i-Vortex as an compatibility option) with optional - for no-headunit.
I see you make a remark on Bushido headunit protocol; do you have a Bushido as well? Is your solution an answer for #117 also? Sorry for messing around with the issue-titles, but I try to keep track of them all.
I had the opportunity to buy a Genius T2020 (with T2022 head unit and T2420 steering frame) for cheap and couldn't resist. So I may have something to contribute soon.
Curious to see if it is a meaningful improvement over the Fortius (apart from getting rid of the cables and the cadence sensor).
@WouterJD no, I do not have a Bushido brake. My remarks on #117 are only based on the reverse engineered bushido protocol mentioned here: https://github.com/fluxoid-org/CyclismoProject/wiki/Tacx-Bushido-Headunit-protocol. My pull request could work with the Bushido as well as the protocol seems to be identical.
However I realized yesterday, that the device ID for the Bushido is different. Therefore some adjustments are necessary in order to support the Bushido.
From my (still limited) research on the Tacx ANT protocol, a big difference between the Genius and the Bushido protocol is that on the Genius you specify a target slope or power and the trainer basically does the rest. The Bushido is more like the Fortius in that you specify a target force instead, where you have to calculate slope, rolling resistance and wind resistance yourself. So without figuring that out, it's unlikely to work properly.
@switchabl okey, I just had another look at the protocol description at Cyclismo Project and it seems the head unit can do this conversion between power and resistance because the head unit protocol is almost identical to the genius brake protocol.
I think this means the Bushido brake unit needs some more work than just changing an ID and will be its own project.
@WouterJD I like your suggested solution to replace the --no-headunit flag by changing the --TacxType argument. I will change the implementation.
What is you opinion on the Vortex / Genius classes; integrate or keep separate? I think for the moment keeping the Vortex / Genius classes separate is the better solution. If someone gets the Bushido to work it might be useful to do some refactoring to reduce code duplication but for the moment I would not combine the two classes.
My apologies, I think you are right. If you connect through the head unit it looks almost exactly like a Genius. It is only when you connect to the brake directly that things get messy (and there is probably little reason to do that?).
Some relevant differences:
In summary, it looks similar enough to give it a go even if you can't test it. But it definitely needs a separate implementation (with maybe a common base class later on).
I've looked at it a bit more closely and can maybe fill in a few blanks.
The target (sub-)page is pretty much already complete on the Cyclismo page: | Bytes | Value | Interpretation |
---|---|---|---|
0 | 0xdc | Page | |
1 | 0x01 | Sub page | |
2 | 0x00 | Slope mode | |
0x01 | Power mode | ||
0x02 | Heart rate mode (not sure that actually works) | ||
3-4 | Int16 | Target slope (0.1%)/power (W)/heart rate (bpm) | |
5 | UInt8 | Rider + bike weight (kg) | |
6 | 0x00 | ||
0xee | Reset distance | ||
7 | 0x00 | Padding |
There is also a wind resistance sub-page: | Bytes | Value | Interpretation |
---|---|---|---|
0 | 0xdc | Page | |
1 | 0x02 | Sub page | |
2-3 | UInt16 | 0.5 * wind resistance coefficient (0.001 kg/m) | |
4-5 | Int16 | Genius: Wind speed (0.01 m/s, tail wind +/head wind -) | |
Bushido: Wind speed (1 m/s, tail wind -/head wind +) | |||
6-7 | 0x00 | Padding |
wind resistance coefficient = air density surface area drag coefficient * drafting factor
At least that is my best guess at the moment, I hope I have worked the units and signs out correctly. There is no page for rolling resistance, but I guess we can absorb any deviations from the internal default (probably 0.004) into the slope.
All integer values are big-endian (MSB first).
I wrote up a summary of the Genius/Bushido protocol here:
https://gist.github.com/switchabl/61f051700b1b91dccbbdea14d9aac70b See next post for current version.
There are still some small gaps and probably some errors.
It looks like the Vortex protocol is really similar too if you control it through the head unit instead of pairing the brake directly (like FortiusANT currently does). So we might share most of the implementation between Genius/Bushido/Vortex.
I added my best guesses for the Vortex protocol, although this is of course completely untested: https://gist.github.com/switchabl/75b2619e2e3381f49425479d59523ead
Amazing work Switchabl! We might be able to get some sort of auto-calibration routine happening with all that information.
Yes, I think so. I still don't have my Genius, but once I get it I will try to get calibration and head unit to work.
So far, this is mostly based on playing around with TTS without the actual hardware and some experimentation/testing will of course be necessary. But I think it is a good starting point.
Great work @switchabl!
I will try to implement the Genius-specific parts and test them.
My Genius finally arrived and I can do some tests of my own now. I also fixed a few typos in the protocol specification (most importantly page 0xdc is used for the calibration command, not 0xac).
I have verified the protocol for the Genius head unit, but I would suggest that we don't implement the head unit in clsTacxAntGeniusTrainer
, since it is technically completely independent from the Genius brake (you could use it without the brake or vice versa). I think it makes more sense to add support for the head unit as a general remote control along with #121.
@switchabl the suggestion to implement the head unit as a separate device seems reasonable for the Genius brake. It would also reduce the line count of the Genius class by 99 lines from 296 to 197.
For the Bushido brake I am not sure if it would not sense as the head unit makes the communication a lot easier. But one may also argue that there is not even a Bushido proof of concept yet so we should not spend too much thought about it.
Yes, I agree, for the Bushido it makes sense to go through the head unit. If we eventually want to support the Bushido brake solo, I can dig a little deeper into the brake protocol as well. But I think the Bushido was always sold with the head unit, so if that is the case that should be low priority.
When I finally get around to finishing the ANT+ remote (I got side-tracked with the Genius), I will implement the Genius remote there. I now have one to test, so that should be easy enough.
The Blacktrack steering thing was also included with my Genius. For now that is maybe not so interesting, but once Bluetooth is available, we could emulate an Elite Sterzo Smart to get steering on Zwift (https://github.com/kwakeham/zwift-steerer/).
Btw here are the FCC application documents for the Genius (+ head unit + steering frame): https://fccid.io/2AAAZ
Maybe not that much interesting stuff in there, but there are some nice photos of the internals. Also a screenshot of their internal test software: https://fccid.io/img.php?id=2089359&img=bg7.png
So apparently the "trigger" calibration command (0xff) triggers the "production calibration". That explains why it is never sent by TTS and there is a risk sending it messes something up. Apart from that nothing surprising.
There are debug commands "contest", "calsrt" (driving the motor in some way) and "antcw", "antrnd" (for radio testing). I already know that there is a debug command "align" that needs to be run after firmware update. But none of that sounds particularly useful.
I couldn't find the non-smart Bushido. Maybe it was never officially sold in the US? The newer Tacx ("Smart") trainers are here: https://fccid.io/2AAMI
I did try my bushido last week with the branch from m472 https://github.com/m472/FortiusANT/tree/c02e8d356fc74b7417cdaaf3dea37b596c5511c2 by just changing the DeviceTypeID to 82, unfortunately that didn't work. I don't have any experience with Python or Ant+, but I tried to study the code and https://github.com/fluxoid-org/CyclismoProject/wiki/Tacx-Bushido-Headunit-protocol. I think the initialisation to the PC connection needs to be done, but I will need to have a better look to see if I can implement this.
Yes, also take a look at my write-up if you haven't already: https://gist.github.com/switchabl/75b2619e2e3381f49425479d59523ead
I think the main thing is to set it to PC control mode (0x04) at the start (by sending 0xac03040000000000). If you set to 0x03 afterwards, apparently the "Start cycling" message comes up, but I think that is optional. Technically, you should keep sending the command until you get confirmation (0xad03040000000000), in case the transmission gets lost. But for a first test you can probably skip that.
We should probably also send a keep-alive page (0x0000000000000000) every ~10s, to prevent it from turning off. Not sure if this is strictly necessary if we are sending other commands continuously anyway.
Maybe you can copy some of the code for the Vortex head unit. It should be very similar in that respect.
There are a couple of other little differences, but for a first proof-of-concept this should be fine. We can worry about the details later.
Maybe not that much interesting stuff in there, but there are some nice photos of the internals. Also a screenshot of their internal test software: https://fccid.io/img.php?id=2089359&img=bg7.png
I happen to have the Genius Test Application - sent to me by Tacx many years ago when I had a hardware problem. Does not seem to run on Windows 10 though. https://drive.google.com/file/d/1WTZMx2FX-tHLR9BjvY4X3AFJOaYP6ux2/view?usp=sharing May be of some use? It also came with some DLL's - I don't know if these are necessary to run this file.
Interesting, thanks! Yes, having a minimal interface for testing could definitely be useful. And yes, the DLLs are unfortunately necessary to run it.
Here's all the files they sent me: https://drive.google.com/file/d/1yuWhBjTc-qMsXde8dE9C5cx2K-UkcwRO/view?usp=sharing
Hope it helps in the reverse engineering.
Hi Wouter & co
First let me introduce myself. I am Simon Perneel, and i'm from Belgium. I recently discovered this amazing piece of software and i wanted to revive my old Tacx i-Genius (T2021, headunit) as Tacx doesn't support it anymore. I was hoping to get it working with Zwift. Today i received my second ant+ dongle and i tried the adapted code of @m472 with support for the Genius. I started FortiusAnt with following commands: python FortiusAnt.py -t Genius- However, i always get this error in the console:
16:01:54,808: Tacx - Pair with Tacx i-Genius
Traceback (most recent call last):
File "FortiusAnt.py", line 538, in <module>
Console.Autostart()
File "FortiusAnt.py", line 169, in Autostart
Tacx2Dongle(self)
File "FortiusAnt.py", line 118, in Tacx2Dongle
rtn = FortiusAntBody.Tacx2Dongle(self)
File "C:\Program Files\FortiusANT-Genius-Support\FortiusANT-Genius-Support\pythoncode\FortiusAntBody.py", line 483, in Tacx2Dongle
rtn = Tacx2DongleSub(self, Restart)
File "C:\Program Files\FortiusANT-Genius-Support\FortiusANT-Genius-Support\pythoncode\FortiusAntBody.py", line 779, in Tacx2DongleSub
TacxTrainer.Refresh(QuarterSecond, usbTrainer.modeResistance)
File "C:\Program Files\FortiusANT-Genius-Support\FortiusANT-Genius-Support\pythoncode\usbTrainer.py", line 667, in Refresh
self.SendToTrainer(QuarterSecond, TacxMode)
File "C:\Program Files\FortiusANT-Genius-Support\FortiusANT-Genius-Support\pythoncode\usbTrainer.py", line 1381, in SendToTrainer
info = ant.msgPageDC_TacxGeniusSetPower (ant.channel_GNS_s, \
AttributeError: module 'antDongle' has no attribute 'channel_GNS_s
What am i doing wrong? I use the Tacx T2028 antenna and a second Cyclplus dongle ( i know there are bad experiences about this dongle, but i already ordered it when i read about this).
EDIT: I am running both FortiusAnt and Zwift on the same Windows 10 computer.
This is what i get in Zwift:
I'm happy to help testing the headunit if I manage to get FortiusAnt working. Anyway, thank you for all the work you put into this project!
Simon
@Sigfreid74 Thank you again! It looks like it supports Bushido and Vortex as well. It kind of works on Windows 10 for me and exchanges some data, but doesn't pair properly for some reason. Have to look into it more carefully, but it might be quite useful.
@simonperneel Yes, it is a work in progress and the current commit seems to be broken. I ran into the same problem when I wanted to test it yesterday, here is my quick-fix: https://github.com/switchabl/FortiusANT/tree/genius. I rode an hour or so on Zwift without issues. Calibration is not yet implemented. If you have a working TTS4, you can use that to run the calibration before you start FortiusANT. If not, power may be a bit off.
Hi guys, thanks for all three work. I was busy with the magnetic trainer.
What is the best branch today for genius and bushido? I will start from there to integrate into the base branch of FortiusANT.
Thank you @switchabl! I will give a try with your fork of the code. What command are you using to start FortiusAnt for the Genius?
@simonperneel I am using python FortiusAnt.py -g -a -t Genius
. The Genius- option will very likely go away (and is gone already in my branch). Let us know if it works for you!
@WouterJD Well, the code is really all by @m472. I've really only done some minor clean-up in my branch for my testing. So I would really defer to him on how to proceed as well.
But in any case, I will try to give a quick status report:
I did a quick test and it appears to be working well for me on Zwift 😃 ! I will do some more workouts in the coming days, and will share my experiences with the Genius ( right now i'm using the branch of @switchabl)
I tried the Genius in power mode for the first time today and it mostly works, but it reacts very slowly. Maybe we need to set a lower flywheel weight in power mode like on the Fortius. Or maybe this is normal and a limitation of the brake. I will investigate tomorrow.
The cadence also reads slightly high on mine (by ~4 rpm). But this definitely not our fault, it is just the number that the brake sends.
So, more on ERG mode:
Tl;dr ERG mode should be much better now with https://github.com/switchabl/FortiusANT/commit/232410a42f0ac7331cb6d30aacdde6adcca4e3ef
I did a few workouts on Zwift the past days with the Genius. It appears to work well and it responds to my trainer. However, i have some issues with it and don't know if these are limitations of FortiusAnt, or just because the Genius is not fully implemented yet. I start FortiusAnt with python FortiusAnt.py -g -a -t Genius
. This is the grade mode I suppose?
The problem is that the targetpower always stays at 100W, and I can only push a higher wattage when I spin faster (higher cadance), but because of this, I reach quickly my highest gear ( wheelspeed 55km/h in FortiusAnt but only around 28 km/h in Zwift sometimes). I'm not sure if Zwift transmits a gradient to my Genius.
Because pushing a high wattage at low cadance is not possible, climbs does not feel very realistic in zwift right now.
Is it just a limitation of the current implementation or am I doing something wrong? Can anyone clarify this? Thanks in advance!
@simonperneel Thank you for testing and for your feedback! No, this definitely not the expected behaviour. The mode, either power or slope is requested by Zwift. So when you start Zwift the target should switch to something like "1%, 143W" (unless you load an ERG-mode workout in Zwift). If this doesn't happen, it sounds like Zwift is not talking to FortiusANT. The only Zwift-related feature that is currently missing is track resistance, so at the moment riding on a dirt road doesn't feel harder than on asphalt. But slope is definitely supported (and has so far worked fine for me) and should feel quite realistic on the Genius up until 10-12%.
You should first check that the simulated trainer is paired as a "Controllable" (and not just a "Power source"). If that doesn't help, run FortiusANT with the -d 127
option to generate a log file and upload that here so that we can see what is going wrong.
Thanks for the fast response! Indeed, there must be something wrong between the communication from Zwift to the Genius. My trainer is paired as a 'Controllable' (see first image). I don't think FortiusAnt is running in grade mode, as I don't see the grade displayed in the GUI in FortiusAnt (see second image).
\ \ \ I did a quick ride in Zwift and generated this log file: FortiusANT.2020-12-05 12-00-20.log Maybe the problem is that I use a cheap ANT+ dongle from Aliexpress next to my original Tacx ant+ dongle? Thanks for having a look.
AliExpress / price is not the issue; as long as it's not the cycplus dongle giving issues. Take care that the dongles communicate with each other; no electronics between them. See manual for explanation.
@simonperneel I don't have as much experience with the log files as @WouterJD , but to me it looks normal, except that we never receive any commands from Zwift. In any case, it doesn't look Genius-related.
It seems that FortiusANT is currently using the Tacx/Dynastream dongle and Zwift is using the Cycplus. It may be worth a try to switch that (don't plug in the Tacx dongle until after FortiusANT is running). Zwift doesn't seem to like the Cycplus dongle either. This sounds familiar: https://forums.zwift.com/t/cycplus-ant-issue/514339
The Zwift logs may or may not be helpful: https://support.zwift.com/locating-log-files-BykKO63fr
Enter cycplus and start FortiusANT + search for hw and start Then enter 2nd dongle and start zwift
Cycplus dongle remains a problem
Minor update: https://github.com/switchabl/FortiusANT/tree/genius
Status:
New version now adjusts wind resistance if supported by the CTP (Zwift does not). I am still confused about the units of the wind speed. TTS seems to assume 100 * wind speed (m/s)
, but reality seems closer to 250 * wind speed (m/s)
. Still, seems to be working fine now using the latter value.
Maybe more importantly, the default wind resistance is now more in line with the other trainers (and the FE-C specification). So doesn't feel like riding a TT bike anymore.
Sometimes the wheel keeps spinning slowly in ERG mode after you stop pedaling. Haven't really found a way to fix that yet.
Calibration is now supported
-n
option. It will say "uncalibrated", but the brake does remember the last value (even if you turn it off), so if you didn't change anything and kept the tire pressure the same, it should be fine.-p 110
is pretty much perfect. YMMV.Head-unit is not supported yet (will do this separately) and the virtual gearbox is not supported right now (and it is not clear if it ever will be, needs more experimenting). I find that higher gradients are not super smooth, but compared to the Fortius quite ridable, so I don't miss it much. On Zwift, maybe set a "Trainer difficulty" a bit lower than 100%, on Rouvy try the new -G
option (for example -G 75/50
) to reduce the simulated gradient a bit if you have problems.
@Sigfreid74 @m472 @trygvelu @mikeymclellan @simonperneel (and anyone else with a Genius) Let me know if you are missing anything or are running into any issues with the current version (https://github.com/switchabl/FortiusANT/tree/genius)
@m472 I hope you are okay with me taking this over, most of the credit for the implementation is yours. I assume you have been (relatably) busy with other things.
@WouterJD If the feedback is good, I will make a new pull-request later this week for inclusion in the main branch.
Hi Wouter, from Melbourne, Australia
FortiusANT is not registering the trainer yet though. Any tips to try and get it working?
Thanks
Originally posted by @Sigfreid74 in https://github.com/WouterJD/FortiusANT/issues/14#issuecomment-667527513