2月はスピード強化月間

1月の石舞台100がちょっときつすぎたので少し休みを入れたいと思いつつ、5月の比叡山国際のことを考えると休んでばかりもいられないので、5月の本番までレースには出ずに、トレーニングに専念することにしました。昨年は、1月の石舞台100、3月の六甲縦走、4月のモンキートレイル、5月の弘法トレイルとほぼ毎月のようにレースに出ていたのですが、ちょっとレースに出すぎで、最後の弘法トレイルの時は腰に疲れがたまっていて万全の体調とは言えない状態で、更にレース中に腸脛靭帯が痛くなるというおまけ付きで、調整がうまくいかなかったと反省しています。
今年は、5月の比叡山国際をメインレースに考えて、それまではトレーニングで調整していこうと思っています。
手始めに2月はスピード系のトレーニングに取り組んでいます。

ペース走のペースがつかめない

先週は12月に引き続きペース走を行いました。
alasixosaka.hatenablog.com
前回のペース走が想定よりも早すぎるタイムが出て5分/kmで5kmを走ってしまったので、今回はもう少しペースを落として5.5分/kmで10kmを目標にしました。ところが、走り出すとまたペースが速すぎて、どうも目標ペースを守ることができません。今回もほぼ5分/kmで推移してしまいました。若いころはもっとたくさん走っていたこともあり、ある程度ペース感覚をつかめていたので、このペースという感じで走り出すとだいたいそのペースで走れていたのですが、トレイル中心で走っているせいもあってどうも平地でのペースがつかめていません。また、ウォッチでペースを確認しようと袖をまくった際にボタンに触れてしまったらしくしばらくウォッチが停止した状態で走ってしまい、更にペースがわからなくなりました。結局帰ってから確かめると9kmをほぼ5分/kmで走っていました。前回とほぼ同じペースでさらに距離を伸ばせたのは良いのですが、次回はどんなペースで走るか悩むところです。距離は15kmくらいまで伸ばしてみたいと思っているのですが。

今週はインターバル走

そして、今週は練習メニューの中で一番嫌いなインターバル走をやりました。3.5分/kmで200mを8本という設定で行ったのですが、ガーミンの設定をミスって、1本目は200mの設定ができていたのですが、そのあとは繰り返しで入れておいたら、1kmの設定になっていて、2本目はなかなか終わらないと思ってペースが乱れてしまいました。3本目からは景色でだいたいの目安をつけ約200mを6本何とかこなすことができました。タイムを見てみると、自分では全くそう思っていなかったのですが、1本目から3本目が設定よりも遅く、4本目から8本目がほぼ設定どおりの時間で走れていました。1本目はガーミンに遅いと言われていたので遅いのはわかっていて、ちょっと設定ペースが速すぎたのかなと思って、多少遅くても構わないと思って2本目以降を走っていました。上に書いたように2本目は設定をミスっていることに気づかずにちょっと距離を走りすぎてしまったので遅いのは仕方ないと思うのですが、3本目、4本目とペースが上がって、4本目以降はほぼ想定通りのペースで走れていました。最後の2本は本当にきつくて、絶対にスピードが落ちていたと思ったのですが、意外でした。しんどかったですが、まあいいトレーニングができたのではないでしょうか。
ただ、石舞台100で痛めて左ひざがまだ完治していないようで、走ると膝に痛みが出る状態です。一進一退では困るので何とか少しづつでもよくなってくれないとと思っているのですが。

石舞台100に参加してきました。

昨年に引き続き石舞台100に参加してきました。
コースがあまりに厳しいので正直もういいかなという思いもあったのですが、昨年の参加者は¥1000引きというのがあったのと、昨年は大雪でアイゼンを着けたり外したりでまともに走れなかった区間が多かったので、一度ちゃんと走ってみたいという思いで参加することにしました。
去年書いたブログの記事を参考に準備をしました。やっぱり記録しておくというのは大事なことですね。
alasixosaka.hatenablog.com
今年は、昨年ほど寒くはないと思っていたのですが、昨年とちょうど同じ時期に寒波襲来で、自宅のあたりは雪がちらついたくらいでしたが、明日香地方は積雪があったようです。まあ、でも大会の当日は暖かくなりそうだったので昨年よりはやや薄手の格好を準備しました。
ウェアは、上がアンダーがパタゴニアのキャプリーンサーマルウェイト、その上にモンベルのクロスランナー、下もモンベルのクロスランナーと去年よりもかなり軽装。シューズは結構悩んだが、雪解けで地面がぬかるんでいることを予想してグリップの良いアルトラのモンブランを選択(結局この予想は外れたのですが)。
ザックは、持ち物が多いのでレイドライトのRepsol24を選択。帽子は去年は耳まで隠れるつば無しのキャップをかぶっていたが、今年はそれは予備にもっていくとして、スタート時点ではいつもかぶっているつば付きの軽量のランニングキャップにした。ポールは腰への負担を考えて今年も使うことにした。
持ち物は昨年とほとんど同じで、アイゼン、ヘッドライトと予備のライト、それぞれの予備電池、ザックにつける赤の点滅ライト。エマージェンシーシート、傷テープ、テーピングテープ、マイカップ、防寒具の長袖シャツ(バーグハウスのメリノ)、タイツ(ファイントラックのドライレイヤーサーモ)、レインウェア(上下)。補給食、水。補給食は今回は、ANDO_、エナジージェル、スポーツ羊羹を各2、ブラックサンダー、チョコ羊羹、エネ餅を各1とミックスナッツを用意した。水は最近の定番のクエン酸と塩(ぬちまーす)を入れたものを用意。塩とぬちまーすのセットはエイドでの補充用に3セット用意した。最近どういう入れ物に入れて持っていくのが良いのか結構研究しているのだが、100均の小さなしょうゆ用ボトルなども試してみたが、口が小さすぎて、まず入れる時にとっても入れにくくて大変なのと、出すときも粉が引っかかって出にくいということで、今回は薬包紙を試してみた。少し入れにくいがまあ何とかうまくいきそうな感じだったのでしばらく続けてみようと思っている。
また、今回はランニングベルトを使ってみた。ランニングベルトに補給食やエイドでもらった水に入れるクエン酸と塩を入れておいてザックを降ろさなくても取り出せるようにしてみた。また、これがあればポールが要らなくなったときに畳んでベルトにつけておける。

前日に爪がはがれる

爪がはがれるというと大事のように聞こえるが、自分にとっては結構いつものことで、長く走ると足の指に内出血が起きて、しばらくたつとはがれるというのを繰り返している。今回は、昨年のダイヤモンドトレイルで内出血したときの爪がはがれたようで、左足の親指の爪がはがれた。右足の方は少しぐらぐらしていたのでそろそろはがれるかな、でもレースの当日までは持ってほしいなと思っていたら、なんと予想外の左足の爪がぽろっとはがれてしまった。はがれるとはがれる前よりは少し柔らかくて弱いので前日にはがれるのはちょっとまずいのだが、まあなってしまったものは仕方がない。最近は、以前にも紹介したシリコンのキャップをはめて走っているのでちょっとましにはなったとは思うのだけれど。
alasixosaka.hatenablog.com

青の交響曲(シンフォニー)で会場へ向かう。

今年はちょっと贅沢して、前から乗ってみたかった近鉄南大阪線をはしる観光列車の青の交響曲(シンフォニー)に乗って阿部野橋から橿原神宮へ向かった。

阿部野橋駅に停車中の青の交響曲

車内はさすがは観光列車という感じで、豪華な内装で、さあこれから走るぞという気分ではなくなってしまう。
途中二上山の麓を通ってダイヤモンドトレイルを思い出した。あれもきつかったが石舞台はさらに厳しい。

車内から撮影した二上山

朝食が少し少なかったのか、少し空腹になったので、ランチパック(ハムと卵)とジャムパンを食べる。
車内は7‐8割がたの席が埋まっていて、この冬のさなかに皆さんどこに向かうのだろうと思っていたら、半分以上が橿原神宮前駅で降りて行った。橿原神宮に参拝するのか有名な今井町を散策するのか、それとも明日香の方へ向かうのだろうか?
橿原神宮前からは明日香を周遊する奈良交通バスで石舞台へ向かう。昨年は大雪で寒かったせいかバスはすいていたが、今年はほぼ満席の状態。同じ大会に参加しそうな格好をした人が2名ほどいた。
会場へは11時半前に到着。スタートまで1時間ほどあるのでちょうどよいあんばい。会場が青空会場であまり早く着きすぎても寒いだけなので。今年は日差しがあって日向は暖かかったのでまだだいぶましだったが。
荷物チェックを済ませて着替えて準備をする。今年は、ヘッドライト、アイゼン、防寒具だけしかチェックされなかった。昨年はもっときっちりとチェックされたのに。あとで考えれば、天候のことを考えて必携装備になっていたものでも、不要な雨具なんかはおいていけばよかったかと思った。まあ、本当に何かあったっときに持ってないと何を言われるかわからないけれども。それに雨具を減らしたくらいでは大して重量も変わらないし。何といっても重いのはアイゼンなので。
スタート前にミニあんぱんを2つ食べる。

スタートから第一エイド

12時半に33kと66kの部がスタート。33kとは言っているがオフィシャルには昨年よりも少し距離が伸びて35.7km。>

スタート前の様子

今年は実況のお兄さんがノリノリで盛り上げてくれていた。この人も全員がスタートした後逆走するといっていて、実際に第一エイドに向かう途中で出会った。ずいぶん早いと思ったら第一エイドからスタートしてゴールに向かっているということだった。それにしても、ここがこのコースで一番きついところなので結構大変だったのではないかと思った。ちなみにこのお兄さんゴールした時も同じ調子でノリノリで実況していた。このハイテンションで夜通し実況するのだろうか?
スタートするとほどなくしてトレイルに入ってきついのぼりが続く。途中に万葉展望台があって明日香村から奈良盆地のあたりの展望が拝める。レースなので当然ゆっくり拝んでいる余裕はない。

展望台からの眺め

展望台を過ぎると勾配は緩くなるがさらに登りが続く。登り切ったところからフラットなトレイルが続き談山神社に出る。昨年は誰もいなかったような気がするが、売店も空いていて売店の方が応援してくれた。談山神社を過ぎてロードに出て、コンビニの所を左に折れてまたしばらくロードを進む。この先が昨年とコースが変わっていて何故なのかと思っていたが、行ってみてわかった。橋の架け替えをやっているらしく、橋を通り越して大きく迂回して川を渡ってまた戻ってくるルートになっていた。そこを過ぎるとまた登りが始まる。はじめは舗装路で緩いが次第にきつくなる。昨年はこの坂の途中で雪が深くなってアイゼンを付けた。ここから音羽山に登る。この登りがこのコース一番のきついのぼり。昨年は補給で失敗したので(結局今年も失敗したのですが)、ここの登りでまず、ブラックサンダーを口にする。音羽山の登りの途中にある観音寺はNHKのテレビで大和尼寺日記という番組(たしか)の舞台になっている。
観音寺を過ぎると本格的な登山道になってさらに登りがきつくなる。音羽山の頂上まで約1時間45分。
そこからは細かいアップダウンを繰り返しながら大峠を目指す。ここの区間の上り下りが結構きつい。ここで、さらにチョコ羊羹を食べる。

大峠へ向かう途中の最後のピーク経が塚

大峠からは下ってロードに出て第一エイドの宮奥ダムに向かうのだが、ここの下りでこの日最初の転倒。さすがに標高が高いところは雪が残っていて滑りそうだと思って気を付けていたが、下りの所で、地面が土に見えるところでも下が凍っているところがあって綺麗に転倒してお尻をしこたま打ってしまった。おかげでしばらくお尻が痛くてスピードが出なかった。ただ、同じようなところはこの後もあって何度も転倒した。結果的にアイゼンを付けた方が良かったのかもと思ってしまう。
大体2時間45分くらいで宮奥ダムに到着。予定では3時間くらいを考えていたので15分くらい早い。エイドで水を補給し、ラーメンとヌガーを食べて、トイレを済ませ、途中で食べる補給食をランニングベルトに補充、この先の劇下りに備えて、ゴム手袋をザックからズボンのポケットに入れる。代わりにスタートしたときにはめていた手袋はザックにしまう。そして出発。エイドでの休憩は3分とか言われるが、トイレに行ったりザックからものを出したりしているとすぐに5分くらいかかってしまう。

長くて苦しい第二エイドまで~ハンガーノックとの闘い~

第二エイドを出てダムを周回して今度は龍門岳へと向かう。
竜門岳への登りはめちゃきついわけではないが、ここまでで結構足を使っているのでかなりしんどい。
このあたりから空腹を覚え始める。昨年は第二エイド手前でハンガーノックになりかけて補給に失敗したと思った、今年はさらに早い段階でハンガーノックになりそうになってきてしまった。ここで、スポーツ羊羹を立て続けに2つ食べる。それでもまだ足りないのでしばらくしてANDO_を食べてなんとかしのぐ。
また、下りの所が劇斜面でロープがあってここが下りの難所。ところが今回は、ロープの手前でまた、凍結しているところがあってここで3回くらい転倒してしまった。転倒するときに踏ん張るもんだから太ももが痛くなってその後が大変だった。ロープのある所は滑りながらでもロープにつかまって降りればよいのでかえって楽だった。
竜門岳から下ってくると一旦ロードに出て林道をしばらく登ってトレイルを上る。昨年はここの登り口を見過ごしてオーバーランしてしまったが、今回は景色を覚えていたこともあって通過することなく入り口を確認できた。しかし、係員を置いてほしいと思う。
ここの登り口昨年は単なるトレイルだったのに、今年は林業の方の作業道になっていて道幅がだいぶ広がっていた。作業道が終わるとまたきついのぼりが始まる。そろそろ日も暮れてきてライトをつけないといけないと思いつつ、登りの途中では道が狭くて作業しづらいのでついつい先延ばしになる。ちょっと緩くなったところで後ろから女性ランナー2人がやってきて抜いていった。先頭の人はもうヘッドライトを点けていた。登り切ったところにあづまやがあったのでここでライトを装着。また空腹感が襲ってきたのでエナジージェルとナッツを口にする。芋が峠の手前もアップダウンが繰り返し、もう足に来ているので登りは走れないし、下りで滑った時に踏ん張ったおかげで太ももが張ってしまって下りもきつい。なんとか5時間半くらいで第二エイドの芋が峠に到着。予定より30分ほど早い。

芋が峠からゴール~足の痛みに耐える~

芋が峠のエイドで水を補給し、ぜんざいをいただいてスタート。残りは9kmくらいでほぼ下りなので最後のひと踏ん張り。
まず最初に少し上る。もう足がほとんどいうことを聞いてくれない。去年もここの登りはきついと思ったのだがあまり進歩がないなあ。
登った後は細かなアップダウンを繰り返す。田口さんは気持ちよく走れる区間と言っているが、足が残ってないので登りが苦痛で、しかも下りは急なくだりは踏ん張れないのと滑らないように慎重に降りないといけないので全然楽しくない。
いい加減くたばったところで高取城跡に入ってようやくここから下りの連続になる。ただ、去年は雪がいっぱいあって気が付かなかったが石がゴロゴロしていて全然走りやすくない。このあたりで左の腸脛靭帯が痛くなってきて下りがさらにつらくなってきた。ようやくトレイルが終わってロードに出るころには完全に左足が痛くなっていた。それでも我慢してロードを走っていると、まえから数個のヘッドライトがこちらに向かってやってくる。はじめは趣味で走っている人かと思ったが参加者だった。曲がり角を通り過ぎていたらしい。たしかにウォッチを見るとルートから外れている。この人たちに出会ってラッキーだった。
少し戻って本来のルートに乗ってしばらく行くと、さっきのロードにまた出た。この区間あんまり意味がないような。
一緒に走っていた人の一人は100kmの参加者でこれからまだあと2周するとのこと。自分は絶対に2周もできないなあと思って尊敬してしまう。
明日香村に入ったところで昨年とルートが変わっていて、大きくアップダウンと迂回をしながら石舞台に近づいていく。去年はロードをまっすぐ行けばよかったので楽だったが、足が痛くて登りも下りも全然走れない。ようやくゴール付近でフラットになって軽いジョグペースで走りながらゴール。
ゴール後にはカレーをいただいた。めちゃめちゃおいしかった。やっぱりカロリーが少し足りなかったようだ。
ゴールタイムはだいたい7時間10分で、昨年よりも40分近く早かったし、目標タイムよりも20分程度早く走れた。とはいえ、最後はバテバテで全然走れなかったし、走り自体満足のいくものではなかった。ちょっと登りで飛ばしすぎたのがばてた原因だと思う。平均ペースで11分半を切っているので、これだけ長く、アップダウンのきついコースで12分以下で走ったというのは自身にはなるがやっぱり飛ばしすぎたという気がする。もう少し登りでペースを抑えておけば後半もうちょっと走れたのではないかというのが反省点。トレランを始めた頃、ペースがつかめず、突っ込みすぎて途中でばてるというのを繰り返していたが、同じパターンをやってしまった。前回走ってコースを知っているというのと、40km以上のレースもこなしているので距離に対する恐怖心が薄れてしまって飛ばしすぎてしまったようだ。もうちょっと、細かくポイントを区切ってペース管理をしないといけないと思った。
また、今回も補給に失敗してハンガーノックになりかけた。お昼にスタートということで、スタート前にパンを食べたが、パンよりもおにぎりの方が良かったというのが実感。途中のエイドでご飯ものが出ないのを知っているのでスタート前にご飯ものを摂取しておくべきだった。やっぱりパンよりもご飯の方が腹持ちが良い。
レーニングの面では、昨年末に長い坂道を走った時に腸腰筋が痛くなったので、その反省として腸腰筋の筋トレをしっかりやったのと、レース前に坂道のトレーニングを取り入れたおかげで腸腰筋は痛くなかった。ただ、左ひざの腸脛靭帯と膝そのものがレース後に痛くなった。レースの翌日で、腸脛靭帯はほとんど痛みがないが、膝は力を入れると少し痛むので、手術した半月板を少し痛めたのかもしれない。坂道で無理に踏ん張ったのがいけなかったのかもしれない。
比叡山まで3か月半くらいなので、これ以上痛めないように用心しながらトレーニングをしないといけない。
比叡山に向けたトレーニングの一環としてはこれ以上ハードなトレイニングはないというくらいハードだったが、レースとしえ考えたときに来年も出るかと言われるとちょっと考えてしまう。下りがきつすぎて足に悪いのと、ゴールが夜になってしまうので帰りがつらい。また、33kのコースは今年が最後かもしれないということだし、2周すれば朝になって帰りやすくなるが、このコース2周できるのかと言われると全然無理そうなのでやっぱり来年は出ないかなと思う。
ゴール後は昨年、駅まで歩いて結構しんどかったのでタクシーで帰ろうと思ったが、タクシーが捕まらず、結局駅まで歩いて帰る羽目になった。
駅に着くとちょうど電車が出たとこだったので、駅前のラーメン屋でラーメンを食べて帰った。ゴールは昨年よりも早かったが結局家に着いたのは同じくらいの時間になってしまった。

PaceProについて

Garmin ConnectにはPace Proという機能があるので今回試してみた。
結論から言うと、トレランには使えないというのが実感。レースでも練習でも、コースを作ると、Garmin ConnectでPace Proが使えるようになる。目標タイムを入力すると、Garmin Connectがコースのアップダウンを考慮してペースを考えてくれるのだが、この機能はどうもロードレース向きの機能のようだ。実際に走ったタイムとPace Proが作ったタイムを比較してみたが、目標タイムよりも大分早く走ったのにもかかわらず、区間タイムがPace Proよりも遅いところが沢山ある。どれも登りの区間で、登りの区間はたぶん走ることを前提でペースが組まれているようで、走れないきつい登りはPace Proよりも遅いタイムになってしまうようだ。ここの登りが走れればとんでもなく速いタイムでゴール出来てしまうだろう。
また、Pace Proをウォッチに転送しておけば、ウォッチがペースを教えてくれるのだが、その時のタイムによってペースをどんどん更新していって、それをいちいち教えてくれるもんだから鬱陶しい。
ということで、Pace Proはレース前にポイントまでの所要時間を計算するときの参考にはなるが、あてにはならないというのが今回の結論。

Garminウォッチ用のデータフィールドを作成する(その2)

前回は、ガーミンウォッチ用のデータフィールドの作成をVisual Studio Codeを使ってプログラムするところまでやりました。
alasixosaka.hatenablog.com
今回は、出来たデータフィールドをウォッチに転送して使えるようにします。
まず、ウォッチフェイスの時と同様に、プロジェクトのフォルダを開いて、binフォルダ内にあるxxxx.prgというファイルを探します(xxxxはプロジェクト名)。
ウォッチをPCに接続して、Appフォルダに先ほどのファイルをコピーします。
PCでの操作はここまで。ウォッチをPCから外して、あとはウォッチ側での操作です。
ウォッチフェイスの場合はここでウォッチフェイスを選択すれば表示されたのですが、データフィールドの場合はもうひと手間必要です。
ウォッチで、Startボタンを押して、データフィールドを追加したいアクティビティを選択します。自分の場合はトレイルランニングに追加したいので、トレイルランニングを選択。Upボタンを長押ししてトレイルラン設定を選択、トレーニングページを選択、そうするとデータフィールドが現れるので、Upボタンを押して追加のページ(画面の中央に緑の+が表示される)を表示させてStartボタンで選択。カスタムデータを選択し、レイアウト選択画面で1項目を選択する。ここで、2項目以上を選択してしまうと、前回シミュレータで表示させたように全項目同じ表示になってしまうので注意。
ここで、一番上に「ConnectIQ 1/xを追加しました」というような表示あるので、これを選択。そうすると、リストにさきほどコピーしたxxxx(プロジェクト名)が表示されるのでこれを選択するとそのアクティビティに自作のデータフィールドが追加される。別のアクティビティ(例えばラン)に追加する場合は同じ操作をランのアクティビティ設定で行う。
追加したら、データフィールドをどの順番に配置するか選択する画面が出てくるので好きなところに配置する。デフォルトだと一番最後に配置される。

別のデータフィールドを作ってみる

もう少し別のデータフィールドも作ってみます。
実は、やりたいことがあったのですが、どうもうまくいかないようです。それは、

distanceToNextPoint、distanceToDestinationは使えない

ということのようです。上の2つのコマンドはAPIのコマンドリストに掲載されていて、ナビゲーション中に次のポイントや目的地(ゴール)までの距離を取得する関数のようです。ところが、FenixやForerunner955などの地図を表示できるデバイスは対応デバイスになっているのですが、Forerunner255は対応デバイスのリストに載っていません。ただ、Instinct2などの地図を表示できないデバイスもリストにあるのでひょっとしたら使えるのではないかと思って試してみました。
結論から言うとForerunner255では使えないようです。Instinct2で使えて、Forerunner255で使えない理由は不明ですが、あると便利な機能なのでちょっとショックでした。一応ナビゲーション中に地図の画面(といっても地形や道路は表示されないですが)からDownボタンでその下の画面に行くとGarminConnectで設定したポイントで次のポイントまでの距離やゴールまでの距離が表示されます。地図画面でもゴールまでの距離は表示されます。
ただ、残り距離を現在時刻やトータルタイムと一緒に表示できればいいなと思ったのですが、どうもForerunner255では無理なようです。
デフォルトの設定でも表示される情報なので、時計の機能自体に対応できないという問題があるわけではなさそうですが、どうもConnectIQのAPIが対応していないようです。
APIにはnameOfNextPointというコマンドもあるので、nameOfNextPointとdistanceToNextPointを表示させるデータフィールドを作ってみました。ナビゲーションを実行しないと機能しない(コースとコース上のポイントを読み込まないと距離の計算ができないはず)なので、実機で、自宅の周りのコースを適当にGarminConnectで作ってウォッチに転送して動かしてみましたが、表示はnameもdistanceもNullとなってデータが表示されませんでした。
ちなみに、ConnectIQストアで次のポイントまでの距離や名前を表示するデータフィールドがあり、対応デバイスにForerunner255が載っていたので、これも試してみましたが、なんか全然変な距離と名前が表示されるだけで全く機能しませんでした。ということで、この機能を実装することは諦めました。

ペースを表示させる

仕方がないので、ペースを表示させるデータフィールドを作ってみました。
表示させるデータは、平均のペースと現在のペース、それに距離と経過時間の4つとしました。データフィールドの区切りは、一番上が距離、真ん中を2つに区切って左が平均ペース、右が現在のペース、一番下が経過時間としました。

ペースを表示させるデータフィールド

全部白黒なのも味気ないので色を付けてみました。
ペースを直接取得する関数はないので、現在のスピードと平均スピードから計算します。現在のスピードはinfo.currentSpeed、平均スピードはinfo.averageSpeedで取得することができます。どちらも単位はm/sとなっています。ですので、この値からペース(分/km)を計算するには、次の式を実行すればよいことになります。
ペース=1000/60/スピード

プログラム

プログラムのソースです。前回のデータフィールドと基本は大きく変わらないので変わったところだけ説明します。

変数
    hidden var mValue as Numeric;
    hidden var valueFormat = "%d";	
    hidden var label = "距離";  // intial value for the label
    hidden var label2 = "平均ペース";
    hidden var label3 = "タイム";
    hidden var label4 = "ペース";
    hidden var clockTime;
    hidden var eTime;
    hidden const ZERO_TIME = "0:00";
    hidden const ZERO_TIME2 = "00";
    hidden var distanceUnits = System.UNIT_METRIC;
    hidden var distance;
    hidden const ZERO_DISTANCE = "0.0";
    hidden var kmOrMileInMeters = 1000;
    hidden var ave;
    hidden var pace;

変数です。label1からlabel4まではデータフィールドの表示するラベルでそれぞれ、距離、平均ペース、タイム、ペースとなっています。あとは、最後の2つaveとpaceを追加しています。それぞれ平均速度、現在の速度を格納する変数です。

onCompute

    function compute(info as Activity.Info) as Void {
        // See Activity.Info in the documentation for available information.
        //clockTime = System.getClockTime();
        //eTime = info.elapsedTime;
        eTime = info.timerTime;
        distance = info.elapsedDistance;
        ave = info.averageSpeed;
        pace = info.currentSpeed;
    }

onComputeも最後の2行が変わっています。aveに平均速度、paceに現在の速度を格納しています。

onUpdate
    function onUpdate(dc as Dc) as Void {
        var width = dc.getWidth();
        var height = dc.getHeight();
        var textCenter = Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER;
        var backgroundColor = getBackgroundColor();
        // set background color
        dc.setColor(backgroundColor, Graphics.COLOR_TRANSPARENT);
        dc.fillRectangle (0, 0, width, height);
        // set foreground color
        dc.setColor(Graphics.COLOR_DK_BLUE, Graphics.COLOR_TRANSPARENT);
        dc.drawLine(0,85,width,85);
        dc.drawLine(0,165,width,165);
        dc.drawLine(width/2, 85, width/2, 165);
        
        dc.setColor((backgroundColor == Graphics.COLOR_BLACK) ? Graphics.COLOR_WHITE : Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
        
        
        
        //var timeString = Lang.format("$1$:$2$:$3$", [clockTime.hour, clockTime.min.format("%02d"), clockTime.sec.format("%02d")]);
        //var timeString2 = Lang.format("$1$:$2$:$3$", [eTime.hour, eTime.min.format("%02d"), eTime.sec.format("%02d")]);
        var duration;
        var duration2;
        // do layout
        if (isSingleFieldLayout()) {
            dc.drawText(width/2, 30, Graphics.FONT_TINY, label, textCenter);
            dc.drawText(width/2, 180, Graphics.FONT_TINY, label3, textCenter);
            //dc.drawText(width/2, 210, Graphics.FONT_NUMBER_MILD, timeString, textCenter);
            dc.drawText(65, 100, Graphics.FONT_TINY, label2, textCenter);
            dc.drawText(190, 100, Graphics.FONT_TINY, label4, textCenter);
            dc.drawText(190, 70, Graphics.FONT_TINY, distanceUnits == System.UNIT_METRIC ? "km" : "mi", textCenter);
            var distStr;
            var aveStr;
            var paceStr;
            System.println(distance);
            if (distance == null) {
                distStr = ZERO_DISTANCE;
                }
            else {
                var distanceKmOrMiles = distance / kmOrMileInMeters;
                distStr = distanceKmOrMiles.format("%.1f");
            }
            dc.drawText(width/2, 60, Graphics.FONT_NUMBER_MEDIUM, distStr, textCenter);
            if (eTime != null && eTime > 0) {
                var hours = null;
                var minutes = eTime / 1000 / 60;
                var seconds = eTime / 1000 % 60;
                
                if (minutes >= 60) {
                    hours = minutes / 60;
                    minutes = minutes % 60;
                }
            
                if (hours == null) {
                    duration = "0:"+ minutes.format("%02d");
                } else {
                    duration = hours.format("%d") + ":" + minutes.format("%02d");
                }
                duration2 = seconds.format("%02d");
            } else {
                duration = ZERO_TIME;
                duration2 = ZERO_TIME2;
            } 
            dc.drawText(110, 210, Graphics.FONT_NUMBER_HOT, duration, textCenter);
            dc.drawText(190, 215, Graphics.FONT_NUMBER_MILD, duration2, textCenter);
            if (ave==null){
                aveStr = ZERO_DISTANCE;
            }else{
                //var aveSpeed = ave*60/1000;
                var aveSpeed = 1000/60/ave;
                aveStr = aveSpeed.format("%.1f");
            }
            if (pace==null){
                paceStr = ZERO_DISTANCE;
            }else{
                //var paceperkm = pace*60/1000;
                var paceperkm = 1000/60/pace;
                paceStr = paceperkm.format("%.1f");
            }
            dc.setColor(Graphics.COLOR_DK_RED, Graphics.COLOR_TRANSPARENT);
            dc.drawText(60, 130, Graphics.FONT_NUMBER_MEDIUM, aveStr, textCenter);
            dc.setColor(Graphics.COLOR_DK_BLUE, Graphics.COLOR_TRANSPARENT);
            dc.drawText(190, 130, Graphics.FONT_NUMBER_MEDIUM, paceStr, textCenter);
        } else {
            dc.drawText(width / 2, 5 + (height - 55) / 2, Graphics.FONT_TINY, label, textCenter);
            dc.drawText(width / 2, (height - 23) - (height - 55) / 2 - 1, Graphics.FONT_NUMBER_HOT, mValue.format(valueFormat), textCenter);
        }

まず、画面のレイアウトですが、画面を4分割するのでそのための線を3本引いています。最初の2本は前回と同じで、3本目が真ん中を2つに分割する線です。
dc.drawLine(width/2, 85, width/2, 165);
それから、平均ペース、現在のペースを格納する文字列変数を定義しています。
var aveStr;
var paceStr;
経過時間の表示が前回は真ん中だったのを今回は一番下にしたので、表示位置を変更しています。
dc.drawText(110, 210, Graphics.FONT_NUMBER_HOT, duration, textCenter);
dc.drawText(190, 215, Graphics.FONT_NUMBER_MILD, duration2, textCenter);
平均ペースと現在のペースの計算と表示ですが

            if (ave==null){
                aveStr = ZERO_DISTANCE;
            }else{
                //var aveSpeed = ave*60/1000;
                var aveSpeed = 1000/60/ave;
                aveStr = aveSpeed.format("%.1f");
            }
            if (pace==null){
                paceStr = ZERO_DISTANCE;
            }else{
                //var paceperkm = pace*60/1000;
                var paceperkm = 1000/60/pace;
                paceStr = paceperkm.format("%.1f");
            }
            dc.setColor(Graphics.COLOR_DK_RED, Graphics.COLOR_TRANSPARENT);
            dc.drawText(60, 130, Graphics.FONT_NUMBER_MEDIUM, aveStr, textCenter);
            dc.setColor(Graphics.COLOR_DK_BLUE, Graphics.COLOR_TRANSPARENT);
            dc.drawText(190, 130, Graphics.FONT_NUMBER_MEDIUM, paceStr, textCenter);

の部分がそうです。距離の表示と同じように、データがない時はそのままだとNullになってしまうので、データがnullの時をif文で判断して、それ以外の場合は計算して結果を文字列に代入して表示しています。処理の流れは距離の所とほぼ同じです。表示する前にカラーを指定して、平均ペースはダークレッド、ペースはダークブルーにしています。
経過時間の表示がデフォルトでも気にならないのなら、このデータフィールドをわざわざ作る意味はあまりありません。前回も書いたように、デフォルトでの経過時間の表示は何故か、分と秒が大きな文字で、時がとても小さな表示になります。ウォッチ自体の設定でこれを変える方法がないので、オリジナルデータフィールドの価値がそこにあります。
また、マラソン大会専用のデータフィールドを作ったりしている人もいるようなので、データフィールドについてはもう少し研究してみたいと思います。

Garminウォッチ用のデータフィールドを作成する

新しく買ったGarmin Forerunner255用に自作のウォッチフェイスを作成しました。いろいろ苦労したのですが、何とか満足のいくウォッチフェイスができました。
alasixosaka.hatenablog.com
ウォッチフェイスの作成に使ったConnectIQはウォッチフェイス以外にもウィジット、アクティビティ、データフィールドの作成などオリジナルのアイテムを色々と作ることができます。
今回は、データフィールドの作成にトライしてみました。
データフィールドを作成しようと思ったのは、アマゾンのレビューにも出ていますが、アクティビティ中の経過時間の表示が、時、分、秒で表示されるのですが、何故か時の表示だけとても小さい文字になっているのです。
www.amazon.co.jp
上のリンクの写真はForerunner955のものですが、Forerunner255でも同様でした。
そこで、自分でデータフィールドを作ればこの問題は解決するのではないかと考えました。
あと、Forerunner955では表示されるみたいですが、Forerunner255ではナビゲーション中の高低図が表示されません。(Forerunner255で高低図が表示されることがわかりました)これもオリジナルのデータフィールドを作ればなんとかなるのではと思っていますが、こちらの方ははるかに難易度が高そうです。ですので、まずは、普通のデータフィールドを作成し、時間の表示を何とかしたいと思います。

はじめは結構戸惑った。

前回の最後に書いたように、ウォッチフェイスの作成については日本語の参考サイトがいくつかったのでその助けを借りてなんとか完成させることができました。
ところが、データフィールドについてはほとんど日本語の”先生”がいないのです。仕方がないので、英語のサイトやAPI を見ながら進めていきました。
結論から言うと、ウォッチフェイスができれば、あまり問題なくデータフィールドも作成することができます(複雑なことをしなければ)。
一番参考になったのはこちらのサイトです。
starttorun.info
データフィールド作成のためのチュートリアルで、ベースはこのチュートリアルのLayout with dc.draw() callsを参考にしました。ウォッチフェイスの時にも書きましたが、文字列、画像などを配置するときにlayout.xmlを使うのか、直接drawコマンドを使うのか2通りの方法があります。layout.xmlを使う方がフレキシビリティーが高く、いろいろなウォッチに対応させやすいという反面、手続きが面倒というデメリットがあります。自分専用に作る場合は手間を考えるとdrawコマンドを使った方が簡単にできます。ただ、デフォルトのひな形はlayoutを使うようになっていたので、始めは、上記のサイトの存在を知らなくて、ひな形を使っていろいろ試していて、うまくいかず、随分時間を使ってしまいました。

出だしの部分でつまずく

上にも書いたようにまず、ひな形を使ってデータフィールドのプロジェクトを作ってみたのですが、まずはデータフィールド用のプロジェクトを作るところでつまずいてしまいました。データフィールドの作成は、Visual Stuido CodeのMonkey C:New projectで作成するのですが、その時、data fieldを選ぶと、simple と complexの2つの選択肢が出てきます。最初、simpleでは表示するデータが1つだけのデータフィールドを作成でき、complexでは2つ以上のデータを表示するデータフィールドを作成できるものと思っていました。また、シミュレーターで、データフィールドを動かすと、data fieldsのタグからlayoutを選択すると表示するデータ項目数を変更することができて、1から6まで選ぶことができます。このこともあり、complexでは2つ以上のデータを表示するためのものと思ってしまいました。なので、始めは、complexを選択し、出来たlayout.xmlを見て、layout idが5つもあるので、これはデータを5個表示する用のひな形だと勝手に思い込んでいました。ひな形を動かすと、心拍数を表示するデータフィールドができているのですが、このとき、シミュレータで先ほどのdata fieldsタブから4のレイアウトを選ぶとこんな感じに全部同じ表示になってしまいます。

4つとも同じ表示に

当然、5つでも同じことで、全部表示が同じです。
これは、layout.xmlでlayout id が全部同じラベルを持っているからそうなるのだと思って、それぞれ違うラベルに変えてみたものの結果は同じで、ここで、ああでもないこうでもないと試行錯誤やWEBサイトの検索を繰り返していました。
そのうちに、データフィールドのMonkey Cプログラムを公開しているサイトを見て、どうしているのかを調べてみると、そんな複雑なことはせずに、自分で勝手に区切りを入れて、その区切りに合うようにテキストを配置しているだけだと気づきました。
たしかに、シミュレータでもウォッチの実機でも、データフィールドを最初から区切っていくことができるのですが、よくよく考えると、そうすることのメリットは、ユーザー側でどこに、どのデータを割り付けるのかを指定できることくらいしかなく、自分で設計して、決めたデータを決めた場所に配置するだけなら、自分で勝手に区切ってその区切り応じて配置した方がはるかに簡単だということにようやく気付きました。まあ、最初から4つなら4つに区切ったデータフィールドに対応してプログラムを書く方法もあるのかもしれませんが、今のところそのやり方を見つけられていません。でも、自分で勝手に区切ればよいのであれば何も難しいことはなく、ウォッチフェイスでやったように、どこに何を配置するかを決めて、フォントサイズなんかを決めてやればいいだけです。区切りの線が欲しければ自分でこれも書いてやればいいだけの話。

プロジェクトの作り方

まあ、ここまでがいつもの前置き(失敗談)で、ここからが本番です。
先のリンクのチュートリアル layout with dc.draw() callsに従ってプロジェクトを作ります。
作り方は、Visual Studio Code でF1、Monkey C: New Project からデータフィールドを選択します。ここで、上にも書いたようにsimple と Complexの選択肢が出てきますが、complexを選びます。データフィールドの名前を適当に入れるとひな形ができます。このとき、上にも書いたようにlayout.xmlを使うひな形できるので、チュートリアルに従い余分なファイルを削除します。

  • まず、layout.xmlを含むフォルダを削除します。これは、Visual Studio Code上で行います。以下も同じです。
  • 次にxxxxBackground.mcを削除します。xxxxはプロジェクト名です。
  • 次に、xxxxView.mcの中の、function onLayout() を削除します。
  • 次に、同じくxxxxView.mcの中のfunction onUpdate()の中身を空にします。

これで準備完了です。あとは自分の好きなようにレイアウトしてデータを配置するだけです。

まず、データ3つのデータフィールドを作ってみる。

トレラン中に絶対に見る情報として、自分の場合は、トータル距離、経過時間、現在時刻の3つです。老眼であることも考えてとりあえず3つのデータに絞って大きめのフォントで見やすいデータフィールドを目指します。もちろん、この3つのデータを並べて表示するだけなら、ウォッチ上で操作して、新規のデータフィールドを作成し、それぞれにトータル距離、経過時間、現在時刻を割り当てれば済む話で、なにもわざわざオリジナルのデータフィールドを作る必要はないはずですが、上の方にも書いたように、そうすると経過時間の時、分、秒の時のフォントがなぜかとっても小さなフォントで表示されてしまい、老眼で読むのはとてもつらいことになってしまいます。もちろん、1時間なのか、2時間なのかは見なくてもわかることが大半だし、現在時刻を見て逆算すれば仮にフォントが小さくて読めなくても見当はつくのですが、疲れてきて、頭が白くなってきた状態でいろいろ考えるのは面倒なので、大きく表示できるのなら表示したい。ところが、ウォッチを操作して作るデータフィールドはフォントの指定ができないという欠点があり、字を大きくすることができないのです。なので、自分でフォントサイズを指定できるオリジナルのデータフィールドの出番です。

配置を決める

配置は、上から順に、トータル距離、経過時間、現在時刻としました。そして、一応仕切りの線を入れてみました。線の色は、ウォッチを操作して作るデータフィールドと区別するために青のラインにしてみました。フォントのサイズは、一番大きい真ん中の経過時間の時と分がFONT_NUMBER_HOT。秒はそれほど重要ではないので少し小さめのFONT_NUMBER_MILDとしました。トータル距離はFONT_NUMBER_MEDIUM。時刻は表示桁数が多いので小さめのFONT_NUMBER_MILDとしています。また、それぞれのラベルは、FONT_TINYを使いました。

今回作ったデータフィールド

プログラム

プログラムの本体xxxxView.mc (xxxxはプロジェクト名)を順番に説明していきます。drawコマンドを使っていますので、本体以外はmanifest.xmlとxxxxApp.mcの2つのファイルだけで、どちらもデフォルトから手を加えていませんので説明は省略します。

モジュールの読み込み

冒頭の部分です。

import Toybox.Activity;
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.WatchUi;

4つのモジュールを読み込んでいますが、この部分はデフォルトのままです。いまだにimportとusingの区別がわかっていません。ネットでよく見るソースコードではたいていusingを使っています。どちらも大差ないようですがとりあえずデフォルトのままにしてあります。

変数

モジュールの読み込みの次からプログラムの本体が始まります。プロジェクト名はdatafield2としていますので、ファイル名がdatafield2View.mcでクラス名定義でdatafield2View extends WatchiUi.DataFieldとデータフィールド関連の関数を呼び出せるように宣言しています。その次がプログラム全体で使う変数群です。

class datafield2View extends WatchUi.DataField {
    hidden var mValue as Numeric;
    hidden var valueFormat = "%d";	
    hidden var label = "距離";  // intial value for the label
    hidden var label2 = "時刻";
    hidden var label3 = "タイム";
    hidden var clockTime;
    hidden var eTime;
    hidden const ZERO_TIME = "0:00";
    hidden const ZERO_TIME2 = "00";
    hidden var distanceUnits = System.UNIT_METRIC;
    hidden var distance;
    hidden const ZERO_DISTANCE = "0.0";
    hidden var kmOrMileInMeters = 1000;

最初の2つ、mValueとvalueFormat はデフォルトの変数ですが、後の方で書くようにデータフィールドの区切りが1つでない時にエラーにならないように一応残してあります。本来の機能には不要です。
その次の3つがラベル用の変数で、それぞれ、文字列の距離、時刻、タイムです。
clockTimeが現在時刻用の変数で、eTimeが経過時間用の変数。ZERO_TIMEとZERO_TIME2はアクティビティーがスタートする前の初期の状態で画面に表示するための定数です。distanceUnitsは距離を表示するための単位(今回はkm)。distanceは距離用の変数。ZERO_DISTANCEは経過時間の時と同じく初期状態表示用の定数です。初期状態では変数にnullが入ってしまうので定数を指定してnullの時に表示するようにしています。kmOrMileInMetersは距離をkmに換算するための計算用の値です。距離はmで得られるのでkmに換算するのに1000で割って計算します。

初期化関数

デフォルトのままです。mValueを使わない場合は2行目は不要です。

function initialize() {
    DataField.initialize();
    mValue = 0.0f;
}
計算

どうもこのcomputeという関数と、後で出てくるonUpdateの関係が良くわかっていないのですが、とりあえず、アクティビティー中の更新されたデータをここで変数に入れるように使うようです。なので、現在時刻、経過時間、距離をそれぞれの該当の関数に代入しています。経過時間は最初info.elapsedTimeとしていたのですが、こうするとポーズを入れても時間がどんどん進んでしまいます。自分の場合、ランやトレランで休憩したときにポーズして時計を止めることはしないのでどちらでもよいのですが、一応ポーズすると時間が止まるinfo.timerTimeの方を選んでいます。

function compute(info as Activity.Info) as Void {
        // See Activity.Info in the documentation for available information.
        
    clockTime = System.getClockTime();
    //eTime = info.elapsedTime;
    eTime = info.timerTime;
    distance = info.elapsedDistance;
        
}
Obscure
function isSingleFieldLayout() {
    return (DataField.getObscurityFlags() == OBSCURE_TOP | OBSCURE_LEFT | OBSCURE_BOTTOM | OBSCURE_RIGHT);
}

これもよくわかっていないのですが、APIを読むとgetObscurityFlagsの説明は以下のようになっています(googleで日本語に翻訳)。

隠されている画面領域を取得します。
非長方形の画面では、画面の特定の部分が隠れます。たとえば、丸いスクリーンは正方形のスクリーンの角を効果的に切り落とします。このメソッドは、デバイス上の隠された画面領域に一致する、WatchUi.DataField.OBSCURE_* 定数によって定義された列挙値の合計を返します。このメソッドの使用は、 onUpdate()の呼び出し中にのみ有効です。

なので、ウォッチのような丸いスクリーンだと結果がtrueになるのかと思われます。この関数は後でonUpdateの所で呼び出しています。

アップデート

onUpdateは長いので少しずつ説明します。
まず、関数内で使用する変数の定義です。画面の幅をwidth、高さをheightに代入しています。また、textCenterには、テキストを真ん中に寄せる設定を入れています。backgroundColorには背景色を入れています(今回は白)。
次の2行が画面消去で、その次の3行が画面の区切り線の描画です。色は青です。

function onUpdate(dc as Dc) as Void {
    var width = dc.getWidth();
    var height = dc.getHeight();
    var textCenter = Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER;
    var backgroundColor = getBackgroundColor();
    // set background color
    dc.setColor(backgroundColor, Graphics.COLOR_TRANSPARENT);
    dc.fillRectangle (0, 0, width, height);
    // set foreground color
    dc.setColor(Graphics.COLOR_DK_BLUE, Graphics.COLOR_TRANSPARENT);
    dc.drawLine(0,85,width,85);
    dc.drawLine(0,165,width,165);
        
    dc.setColor((backgroundColor == Graphics.COLOR_BLACK) ? Graphics.COLOR_WHITE : Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);     

次が距離と時刻と経過時間の表示の部分です。
まず、現在時刻をtimeStringの文字列に代入します。
durationは経過時間の時、分、表示用の変数で、duration2が経過時間の秒、表示用の変数です。秒は小さいフォントで表示するので変数を分けています。
その次が画面全体のレイアウトの部分です。先ほど定義したisSingleFieldLayoutを呼び出して、trueならif文の中を実行してレイアウト表示をします。距離、経過時間、時刻のラベルを表示しています。現在時刻の表示もここで行います。
distStrは距離用の変数です。その次のif(distance==Null)の所が上で説明したアクティビティースタート前で距離がゼロの時Nullになっているときの処理です。elseの所が距離が何等かあるときの処理で距離数をkmに直して先ほどのdistStrという変数に文字列で代入しています。その下のdrawコマンドが距離の表示です。
その下からが経過時間表示の処理で、eTimeに何らかの数値が入っていれば経過時間に文字列を代入します。このとき、上で書いたように時、分と秒で分けて文字列を作成します。最後のelseの処理は数値がなくNullの場合で、初期値用の文字列を代入します。
最後の2行のdrawコマンドで経過時間を表示しています。

    var timeString = Lang.format("$1$:$2$:$3$", [clockTime.hour, clockTime.min.format("%02d"), clockTime.sec.format("%02d")]);
    var duration;
    var duration2;
    // do layout
    if (isSingleFieldLayout()) {
        dc.drawText(width/2, 30, Graphics.FONT_TINY, label, textCenter);
        dc.drawText(width/2, 180, Graphics.FONT_TINY, label2, textCenter);
        dc.drawText(width/2, 210, Graphics.FONT_NUMBER_MILD, timeString, textCenter);
        dc.drawText(width/2, 100, Graphics.FONT_TINY, label3, textCenter);
        dc.drawText(190, 70, Graphics.FONT_TINY, distanceUnits == System.UNIT_METRIC ? "km" : "mi", textCenter);
        var distStr;
        System.println(distance);
        if (distance == null) {
            distStr = ZERO_DISTANCE;
             }
        else {
            var distanceKmOrMiles = distance / kmOrMileInMeters;
            distStr = distanceKmOrMiles.format("%.1f");
        }
        dc.drawText(width/2, 60, Graphics.FONT_NUMBER_MEDIUM, distStr, textCenter);
        if (eTime != null && eTime > 0) {
            var hours = null;
            var minutes = eTime / 1000 / 60;
            var seconds = eTime / 1000 % 60;
                
            if (minutes >= 60) {
                hours = minutes / 60;
                minutes = minutes % 60;
            }
            
            if (hours == null) {
                duration = "0:"+ minutes.format("%02d");
            } else {
                duration = hours.format("%d") + ":" + minutes.format("%02d");
            }
            duration2 = seconds.format("%02d");
        } else {
            duration = ZERO_TIME;
            duration2 = ZERO_TIME2;
    } 
    dc.drawText(width/2, 130, Graphics.FONT_NUMBER_HOT, duration, textCenter);
    dc.drawText(220, 140, Graphics.FONT_NUMBER_MILD, duration2, textCenter);

最後は上にも書いたようにおまけですが、isSingleFieldLayoutがFalseの時(データフィールドが複数に区切られているとき)の処理で、label(ここでは距離)とmValueを表示しています。mValueは何も計算していないので常にゼロです。ここはレイアウトの紐づけを間違わなければ本来不要のはずです。

    
    } else {
        dc.drawText(width / 2, 5 + (height - 55) / 2, Graphics.FONT_TINY, label, textCenter);
        dc.drawText(width / 2, (height - 23) - (height - 55) / 2 - 1, Graphics.FONT_NUMBER_HOT, mValue.format(valueFormat), textCenter);
    }

ちなみにシミュレータでデータフィールドのレイアウトを3分割にするとこんな感じになります。

ウォッチ側で3分割を選択した場合。

やっぱり3つとも同じ表示になってしまいます。

だいぶ長くなったので今回はここまでにしようと思います。次回は、実機に作ったデータフィールドを転送するやり方と、また別のデータフィールドについて書いてみたいと思います。

一人北摂フォトロゲ

12月に行われた北摂フォトロゲのお手伝いに行った時に地図をもらっていたので、その地図を使って、一人でフォトロゲをやってみました。
フォトロゲとは、フォトロゲイニングの略で、ロゲイニングというのは、地図を持って、地図に書いてあるポイントを回って制限時間内にどれだけ多くのポイントを取れるかを競う競技です。オリエンテーリングをやったことがある人なら、スコアオリエンテーリングのようなものと言ったらわかりやすいかもしれません。
フォトロゲでは、ポイントに行ってもオリエンテーリングのようにフラッグが置いてあるわけではなく、パンチもありません。通過証明には現地に行って写真を撮ってくるという方法を使います。なのでフォトロゲイニングと呼ばれます。
北摂フォトロゲでは、ポイントでクイズやじゃんけんといった遊びの要素は全くなく、時間内に多くのポイントを集めるというのが競技の規則になっています。
また、ロゲイニングは通常2人以上のグループで参加するのが普通ですが、北摂フォトロゲでは一人で参加するソロのクラスもあります。競技の時間は3時間のクラスと5時間のクラスがあります。今回は5時間を想定してコースを組んでみました。優勝チームだと40km以上走るのだそうですが、さすがにそこまでの走力はないので、一応目安として12分/kmのペースで行くと考え25kmくらいのコースを組んでみました。また、本来のスタートゴールはJR高槻駅から京都方面に少し行ったところにある安満遺跡公園なのですが、自宅から安満遺跡公園まで出かけてスタートするのもだるいのでJR高槻駅をスタートゴールにしてみました。
そして、少し反則気味なのですが、あらかじめルートを組んでおいてそれをガーミンのForerunner255に入れておいて走りながらルートに乗っているかどうかを確認して走ってきました。少し反則と書いたのは、ルール上はスマホのアプリは使用OKなので、作戦タイムが20分あるのでその間に、Garmin Connectでルートを組んでウォッチに転送すればルール上は問題ないということになります。ただ、今回は、スタート前の20分間でもなく、アプリでなくPCでコースを組んだのでやや反則という感じです。アプリでもできないことはないのかもしれませんが、やったことがないのでどこまで細かいルートが設定できるのかはわかりません。
まあ、ロゲイニングをしつつ、1月末の石舞台100へ向けてのトレーニングという意味合いもあるので、その辺はまあ良しとしようかと。

出だしでいきなりつまづく

JR高槻駅を9時頃にスタート、5時間の予定なので、午後2時にゴール予定です。ちなみに、大会の本番では、タイムオーバーは1分毎に100ポイントの減点とかなり厳しいルールになっています。
さて、最初のポイントは不老水です。能因法師が不老不死を願って煎茶にして飲んだ水だとか。今は飲めないそうですが。
ポイントは18点です。ポイントは、スタート地点からの距離や登りなどに応じて割り振られています。当然遠いところが高い得点です。ここは近場なので非常に低い点数ですが、通り道なので寄っていくことにしました。
ところが、住宅地の中で道が入り組んでいてどこにいるのかわからなくなってしまいました。はじめは、駅からまっすく北に向かって天神さんの所を右に曲がって天神さんの脇を巻くように北上したところまでは良かったのですが、そのあとが道がわからず、マップとスマホのアプリの地図を見比べてなんとか現在地を割り出してたどり着くことができました。オリエンテーリングでは反則の方法です。まあ、ロゲではOKなんですけど。オリエンティアとしてはちょっと情けない。ただ、言い訳を書いておくと、ロゲの地図はオリエンテーリングの地図と違って道がとても見づらいのです。オリエンテーリングではある程度の太さの以下の道は全部同じ太さで書かれていて、実線と点線などの区別であらわされていて、道が非常に見やすく工夫されているのですが、ロゲの地図は国土地理院の2万5千分の1の地図をベースに書かれていて、しかも細い道は本当に細く書かれていて老眼にとってはものすごく見づらいものになっています。また、縮尺もオリエンテーリングでは1万分の1や7千5百分の1といった縮尺を使うのでかなり見やすいのですが、ロゲでは使うエリアが広いのでどうしても2万5千分の1などの縮尺になってしまうので全てが小さく書かれていて非常に見づらく、特に住宅街などの入り組んだところは非常に苦労するということが今回わかりました。
17分ほどかかってようやくポイントを発見。平地にもかかわらずkmあたり10分越えのスローペース。

最初のポイント不老水

次は、名神を越えた先にある神峯山寺への道標です。古曽部の運動公園の脇を抜けて名神まで登り、名神を越えてまた下って、川沿いを北上したところにありました。ここは比較的簡単にたどり着くことができました。ここのポイントは26点です。

神峯山寺への道標

次はタチソ地下壕跡です。道標のあった川沿いの道を北上し、弥生が丘の住宅地の入り口付近です。ここもすんなりと行くことができました。
タチソ地下壕とは、戦時中に計画された工場の跡らしいです。工事中に終戦になって使われることはなかったらしいですが。ここは29点です。

タチソ地下壕跡

だらだら登りに苦しむ

その次は、最高得点のポイント、神峯山寺の仁王門です。ここは102点です。
タチソ地下壕から川沿いに進み、そのあと新名神を右手に見ながら進みます。このあたりからのぼりが始まります。そして、原からのポンポン山への登山道と合流し、しばらく登ると神峯山寺に到着です。ポンポン山の登山道は何度か通ったことがあるのでここは簡単でした。

神峯山寺の仁王門。正月だからなのか飾りつけされていました。

ここで、トイレ休憩。今日はどうもトイレが近い日らしく、スタート前にいっておいたのですが、ここでも行くことに。タイムロスなのですが仕方ありません。
次のポイントは諏訪神社です。諏訪神社へは、ポンポン山への登山道をしばらく登って、途中で分岐を右に進み、またひたすら上る。そして少し下ったところの集落にありました。集落の中の道がえらい狭くて、人が2人並んで通れないんじゃないかという細さで、入り口を入るのを躊躇しましたが、問題なく到着。
ここは68点です。

諏訪神社。集落の奥まったところにある。

実は、諏訪神社のすぐ近くに77点のポイントがあるのですが、タイムと距離のことを考えて今回はパスしました。競技を真剣にやっている場合、ここまでの経過時間を見てどうするか判断することになるのでしょう。
次は、大沢の杉です。諏訪神社から元来た道に戻って、柳谷へ向かう道をまたひたすら上ります。ここまでの登りはほとんどが急勾配と呼べるようなところがなく、走ろうと思えば走れるところなのでかえってしんどい。どうもこういう登りは苦手なんです。でも、トレーニングのために来ているという側面もあるので頑張って登ります。登りの途中で腸腰筋が痛くなってきました。もう少し鍛えておかないとだめなようです。まあ、筋肉痛なので我慢できる範囲なので我慢しながら進みます。上り坂を上り切ったあたりに大沢の杉への入り口がありました。車道から右に入って斜面を登ると本当に立派な杉が鎮座しています。ここは83点です。

大沢の杉。ここまで立派な杉を実際に見たのは初めて。

ようやくトレイルに

大沢の杉の次は、トレイル途中にある119番通報ポイントB-12です。ハイキングコースなんかによくある、迷ったときに今どこにいるかを消防に連絡する例の奴です。大沢の杉から元来た車道に戻って、しばらく進んで、柳谷まで行かずにギロバチ峠への道を右に入ります。最初は柳谷観音を回るルートを考えていたのですが、そこまで行くと距離が30kmを越えてしまいそうなので手前で曲がって引き返すルートにしました。
ギロバチ峠への道からようやく本格的なトレイルに入りました。峠まではすぐで、あとはひたすら下りです。下りの途中に119番通報ポストがありました。ここは71点です。

トレイルの途中にある119番通報ポスト

次は若山神社です。トレイルをひたすら下って、柳谷から下ってくる車道と合流し、しばらく下った集落のあたりからまたトレイルに入りなおします。ここで、本来は集落の手前の橋を渡ると近道だったのですが、道が読み切れずに、1つ橋を行き過ぎて2番目の橋を渡ってしまい、かなり大回りなルートになってしまいました。本当に集落のあたりはわかり難い。
ここのトレイルは比較的平坦で若山神社に到着。僧行基文武天皇に勘定したのが始まりとか。結構立派な神社で参拝客も何人かおられて、おみくじやお守りを売っている窓口もありました。ここで、またトイレ休憩。そして、お昼近くになって来たし、日差しの当たるところにベンチがあったのでここで昼食のおにぎりを2つ食べる。ここは54点。ゴールに近くなってきたので点数が下がってきました。

若山神社

最後の登り

若山神社からは太閤道を通って、ベニーカントリークラブの淵まで一気に登ります。ここが今日のコース一番の急登でした。まあ、それほど長くないのですが。
ただ、ベニーカントリーまで行けば登りは終わりかと思っていたら、ゴルフコースの淵の道は結構アップダウンがあって、こっちの方が精神的にきつかったです。
ゴルフコースの淵の道を外れて南下してしばらく行ったところにある展望所が次のポイントです。ここが56点。

島本の展望所。遠くに三川合流地点が見える。

その次は安満宮山古墳です。展望所からトレイルを進んで、若山まで登り、そこから降りると高槻市営の公園墓地に裏から入る形になるのですが、途中で少し北西にわき道を入ったところにまた別のポイントがあって、ここも競技だったら残り時間を考えて寄るかどうかを検討する場所になりそうなところでした。今回は、とりあえず25kmを走るということを目標にしていたのと、足の痛みを抱えていたので予定通りパスして安満宮山古墳に向かいました。

コースの途中にあった若山。ここはポイントではないですが。

若山からトレイルを下ってくると高槻市営公園墓地に裏から入る形になります。古墳は高槻市営公園墓地の中にあります。この古墳は3世紀ごろのもので、卑弥呼が魏の皇帝からもらったといわれている三角縁神獣鏡も出土したそうです。ここが38点。

安満宮山古墳。
古墳から見た高槻市内の風景

さて、次が最後のポイントです。得点はなんと6点。安満遺跡公園のすぐ北にあるJRの踏切です。
墓地の中を降りてきて、名神新名神のジャンクションの所から、しばらく川沿いに進んで、そこから南下すればよいのですが、ここもまた市街地になって、どうも現在地がつかみづらい。まあ、だいたいの位置はわかっているので、適当に南下できる道をたどっていったらドンピシャで踏切に到着。
この踏切には、警報機もなく、自動で降りてくる遮断器もありません。遮断機はあるにはあるのですが、手で上げ下げするという変わった踏切です。
何故こうなっているのか詳しいことはわかりませんが、ここで横断するのは車庫へ続いている線路で、車庫へ向かう列車は速度を落としてゆっくり進むので、運転手が目視で確認しながら通るので問題ないということなのかもしれません。その脇にある東海道線の線路には、ちゃんと警報機と自動遮断機がついています。

JR高槻駅の近くにある手動遮断器

ゴールへそして結果は?

遮断機が最後のポイントで、後はゴールするだけです。ゴールはスタートと同じくJR高槻駅に設定したので、駅に向かいます。本来なら遮断機から元来た道を引き返して、西国街道を進むのが早いのですが、せっかくなので踏切を渡って南側に出て、安満遺跡公園との間の道を進み、八丁畷の交差点から北上してきた道とぶつかるところで、線路を渡り、線路沿いにしばらく進み、西国街道に一旦合流。そして、しばらく西に進んでまた、左に折れて線路沿いに進んで高槻の駅に到着。
タイムは4時間25分14秒。ということで35分ほど早く着いてしまいました。結果論ですが、あと一つくらいはポイントを取れていたと思います。この辺が競技の本番になると難しいところだと思います。タイムオーバーすると激しく減点されるので絶対に時間内にゴールしないといけないのですが、余裕を見すぎると今回のようにかなり時間が余るということになってしまいます。
得点は593点でした。優勝チームは1000点を越えているので全然ですね。まあ、それでも1月末の石舞台100はもっとアップダウンが激しいですが距離は35kmなので、今回25kmを走ったことは大会前の練習としてはまずまずだったのではないかと思っています。

1年の計は元旦にあり

あけましておめでとうございます。
今年は、子供が大学受験ということで、久しぶりに我が家で過ごす正月となりました。なので、あまり正月気分がないですが。
とはいえ、1年の計は元旦にありとか。ということで、昨年は何を書いたか見返してみると、目標にトレランで50km、ウォーキングで100kmと書いていましたが、結局どちらも実行することはできずじまいでした。ウォーキングは結局イベントに参加せず。個人的にも長距離のウォーキングはやらずじまいでした。トレランの方は弘法トレイルの44kmを完走したので、まあ近い線まで行ったかなというところ。
さて、今年の目標は、やっぱり、トレラン50kmにウォーキング100kmとしておきます。トレランでは、今年は比叡山国際トレイルランの50kmにエントリーする予定です。制限時間が11時間と厳しいので完走できるかどうかはわかりませんが、今年の第一目標として完走を目指したいと思っています。
また、来年にはUTMFのKAIにチャレンジしたいと思っているので、それに向けて秋頃に100kmウォーキングをやりたいと思っています。今のところ、木曽路の100kmが時期的にちょうどよいかなと思っています。

プロフィールを更新しました。

昨年で還暦になって、今年は61になりますが、プロフィールがブログを始めたときのまま、還暦までに100kmを目指すことになっていたので、更新しました。
プロフィールの所にも書きましたが、最近はトレランで100kmはちょっとあきらめモードです。というのは、走っていると胃がなかなか食べ物を受け付けないので長時間のレースとなると最後まで持たないような気がしています。年のせいなのか、元々そういう体質なのかわかりませんが、たいてい長距離のレースをすると、終わってしばらくするとお腹がすいてくるというパターンで、半日程度のレースなら何とかなるのですが、丸1日かかりそうな100km程度のレースとなるとそんな感じではハンガーノックに陥って動けなくなるのではと思っています。まあ、やってみないとわかりませんが、とりあえず100kmウォーキングをやってみてその時の体の反応を確かめようかとは思っています。

今日は、とっても短い文章になってしまいましたが、本年もどうかよろしくお願いします。

やればできる! 5分/km

比叡山国際トレイルを完走するためにスピードをもう少しつけないといけないということで、久々にペース走をやってみました。
ペース走は本当に久しぶりです。たぶん、ロードレースにまだ出ていた30代の頃以来ではないでしょうか?
GarminのForerunner255はペース走の機能があるのでこれを使ってみました。さすがは、ランニング用ウォッチ。
やり方は簡単です。
Garmin Connect(アプリでもPCでもどちらも可)で、トレーニングと計画→ワークアウトと進んで、ランワークアウトを作成、そうするとウォームアップとクールダウンに挟まれたランワークアウトができるので、ワークアウトを編集、タイプの所でペースを選択し、ペースを設定し、目標の距離を入力すれば出来上がりです。今回はペースを6分/km、距離を5kmとかなりぬるめの設定にしました。ペースを6分/kmとしたのは、最終的には15kmくらい同じペースで走り続けられるようにと思ったからで、とりあえず今回は手始めとして5km走ってみようということでした。本当に久しぶりなので。

作成したワークアウト

ワークアウトができたら、デバイスに転送し、アクティビティメニューでランを選択、UPボタン長押しで、トレーニング→ワークアウトと進んで、さっき作ったワークアウトを選択してスタートすれば始まります。
自分の場合は平地で走るときはだいたいいつも近所の河原に行って走るので、そこまでの行きをウォームアップ、帰りをクールダウンとしました。スタートするとウォームアップが始まります。河原に着いたところでラップボタンを押すと、ペース走の始まりです。
GPSで距離とペースを測るので、今のペースが速いか遅いかを判断してガーミンが教えてくれます。ところが、始めガーミンに遅い、遅いと言われてペースを上げて走ったら5分/kmくらいのペースになってしまいました。どうも、ペースを設定するときにきっちり6分/kmにしたくて、幅を持たせずに最低と最高をどちらも6分/kmにしたのが良くなかったようです。少し幅を持って5分50秒~6分10秒という感じにした方が良かったのではないかと思います。
それにしても、最近は5分/kmで走り続けるということは全くしていなかったので最初はきついと思ったのですが、ペースに乗ってしまうとそのままのペースで走ってしまいました。5km持つのかなと思いつつ、まあいいやと思って走っていると5kmまでほぼ全てのラップで5分/km以内で走り切ることができました。

今回のペース走のラップ

1-2kmの所で5分/kmを少し超えていますが、最初の1kmが設定よりも早すぎたので6km/分に落とそうと思って少しペースダウンしたので少し超えています。結果的にはこの時も一回遅いと言われてペースを上げてまた5分/kmよりも早いペースに戻っています。河原を走っているので多少のアップダウンがあるのですが、基本的に行きが下りで帰りが登りなので、帰りの方がちょっとペースが速い感じです。これは、体がこのペースに慣れて少し楽になったからだと思います。今日の感じだと5kmよりももう少し同じペースで走れそうな感じでした。5分/kmは今の自分にはかなり速いペースと思っていましたが、やればできるもんだと、ちょっと自信がつきました。まあ、昔は4分/kmでハーフマラソンくらいは走っていたことを考えるとずいぶん遅くなったという気がしますが、年を考えれば十分できたかと思います。なので、最初6分/kmで距離を伸ばしていこうかと思っていましたが、5分/kmでもう少し頑張ってみようかと思っています。

比叡山国際トレイルランの日程が発表されていた

来年の比叡山国際トレイルランの日程が発表されていました。公式ホームページを何度か確認していて2023年バージョンから全然変わってなかったので、来年本当にやるのか心配になっていました。今年は昨年の12月23日から申し込みが開始されていて、その日を今年は過ぎてしまっていたもので。
ホームページの下の方にあるFacebookのリンクをクリックするとFacebookのページの方に予告が出ていました。
それによると、開催日は5月11日(土)、エントリーの開始は1/26(金)の夜8時となっていました。石舞台100の前日ですね。今年よりも1か月以上申込期間が後ろ倒しになっていました。色々と準備の都合もあるのでしょうが、ちょっと心配しました。