未分類

hakata_ex_cost_db=# \e 
 start_seq | end_seq | line_name
 -----------+---------+-----------------------------------

1 | 6 | Dummy Railway Line JR鹿児島本線
7 | 7 | Dummy Railway Line JR篠栗線
8 | 10 | Dummy Railway Line 地下鉄航空線
12 | 12 | Dummy Bus Line 天神エリア限定バス
という結果が出てきました。start_seq と end_seq が同じ番号になっているところがありますが、これは、どのように解釈すれば良いでしょうか


SELECT seq, node, edge, cost, agg_cost FROM pgr_dijkstra('SELECT gid as id, source, target,length_m as cost FROM ways',66619, 92554, false);

WITH path AS ( SELECT seq, node, edge, cost, agg_cost FROM pgr_dijkstra( 'SELECT gid as id, source, target, cost, reverse_cost FROM ways', 66619, 92554 ) ), full_path AS ( SELECT path.seq, path.node, path.edge, path.cost, path.agg_cost, ways.length_m AS length_m, ways.name AS line_name FROM path LEFT JOIN ways ON path.edge = ways.gid ) SELECT seq, node, edge, cost, agg_cost, length_m, line_name FROM full_path ORDER BY seq;

----- ダイクストラ66619, 92554 の結果の一覧表示

WITH path AS (
    SELECT 
        seq, 
        edge, 
        b.name AS line_name,
        b.the_geom
    FROM 
        pgr_dijkstra(
            'SELECT gid as id, source, target, cost, reverse_cost FROM ways',
            66619, 92554
        ) a
    INNER JOIN 
        ways b 
    ON 
        a.edge = b.gid
    ORDER BY seq
)
SELECT 
    MIN(seq) AS start_seq,
    MAX(seq) AS end_seq,
    line_name
FROM 
    path
WHERE 
    line_name LIKE '%Dummy Railway Line%'
    OR line_name LIKE '%Dummy Bus Line%'
GROUP BY 
    line_name
ORDER BY 
    start_seq;

以下のSQL文で、"Dummy Rail Line""Dummy Bus Line" に該当する start_seqend_seq を取得できます。


SQL文

WITH path AS (
    SELECT 
        seq, 
        edge, 
        b.name AS line_name
    FROM 
        pgr_dijkstra(
            'SELECT gid as id, source, target, cost, reverse_cost FROM ways',
            66619, 92554
        ) a
    INNER JOIN 
        ways b 
    ON 
        a.edge = b.gid
    ORDER BY seq
)
SELECT 
    MIN(seq) AS start_seq,
    MAX(seq) AS end_seq,
    CASE 
        WHEN line_name LIKE '%Dummy Railway Line%' THEN 'Dummy Rail Line'
        WHEN line_name LIKE '%Dummy Bus Line%' THEN 'Dummy Bus Line'
    END AS line_type
FROM 
    path
WHERE 
    line_name LIKE '%Dummy Railway Line%'
    OR line_name LIKE '%Dummy Bus Line%'
GROUP BY 
    CASE 
        WHEN line_name LIKE '%Dummy Railway Line%' THEN 'Dummy Rail Line'
        WHEN line_name LIKE '%Dummy Bus Line%' THEN 'Dummy Bus Line'
    END
ORDER BY 
    start_seq;

 

SQL文のポイント

  1. WITH句で経路情報を取得:
    • pgr_dijkstra の結果に ways.name を結合して、全経路のエッジ情報を準備します。
  2. CASE文で分類:
    • line_name に基づき、Dummy Rail LineDummy Bus Line の2種類に分類します。
    • この処理により、元の路線名が詳細でも、2つのカテゴリに整理されます。
  3. MINMAX で開始と終了を取得:
    • 経路順序 (seq) の最小値 (start_seq) と最大値 (end_seq) を取得します。
  4. グループ化:
    • CASE文で分類された路線タイプごとにグループ化 (GROUP BY) します。
  5. ソート順序:
    • 結果は start_seq の順に並びます。

結果例

以下のような結果が得られます:

start_seq end_seq line_type
1 10 Dummy Rail Line
12 15 Dummy Bus Line

注意事項

  • 必要に応じて、WHERE 条件や LIKE 演算子を調整してください。
  • 出力をさらに簡潔にしたい場合や、追加情報が必要な場合はお知らせください。適切に対応します。

 

未分類

select * from ways where name LIKE '%Dummy Railway Line%'; で選ばれたnode とwayを全部削除するにはどうしたら良いですか

ways テーブルにおける name 列の内容が '%Dummy Railway Line%' に一致する way と、それに関連する node を削除するには、以下の手順を実行します。ways テーブルと ways_vertices_pgr テーブルのリレーションを考慮した方法です。


手順

1. name 列が空か確認

name 列の値がすべて NULL または予期しない値かもしれません。以下のクエリで name 列の値を確認します。

SELECT DISTINCT name FROM ways WHERE name IS NOT NULL;

 


2. 削除対象の gid を確認

対象となる gid を取得します。もし name が NULL である場合には以下のように NULL 対応を追加してください。

SELECT gid FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL;

 

もし上記クエリに結果がない場合、代わりに以下を確認します。

  • tag_idrule 列など他の列に対象の特徴があるか確認する。
  • 該当の値を直接確認する(例: IS NOT NULL を使う)。

3. 関連する node を特定

sourcetarget のノードが ways_vertices_pgr テーブルに存在する場合、それを削除します。

以下のクエリで関連する sourcetarget を確認します。

SELECT source, target FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL;

 

これにより、削除対象のノード sourcetarget を特定できます。


4. 関連する ways_vertices_pgr の削除

取得した source および target に基づき、ways_vertices_pgr テーブルからノードを削除します。

DELETE FROM ways_vertices_pgr WHERE id IN ( SELECT source FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL UNION SELECT target FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL );

 


5. ways テーブルの削除

最後に ways テーブルから該当する行を削除します。

DELETE FROM ways WHERE name LIKE '%Dummy Railway Line%' AND name IS NOT NULL;

 


注意事項

  • バックアップを作成: データ削除は不可逆操作です。削除前にバックアップを必ず取得してください。
  • インデックスを活用: クエリ性能を向上させるため、適切なインデックスがあるか確認します(ways_pkey など)。
  • 依存関係: 外部キー制約があるため、削除の順序(ノード懼ウェイ)を守る必要があります。

これにより、name LIKE '%Dummy Railway Line%' に該当するデータを完全に削除できます。

この方法だと関連のあるnodeも消してしまうような気がします。wayだけ消せれば良いのです。

関連のある node を削除せずに、ways テーブルだけから特定の way を削除する場合、以下の手順で進めることができます。


方法

1. 削除対象の gid を確認

name に基づいて削除対象の waygid を確認します。

SELECT gid FROM ways WHERE name LIKE '%Dummy Railway Line%';

 


2. ways テーブルから対象の行を削除

特定した gid を使って ways テーブルから削除します。関連ノードは削除されません。

DELETE FROM ways WHERE name LIKE '%Dummy Railway Line%';

 


外部キー制約について

ways テーブルには外部キー制約が設定されていますが、ways テーブル自体からの削除では関連ノード(sourcetarget)を削除する必要はありません。外部キー制約は、通常、ノードが削除される際に ways のデータが参照整合性を保つようにするためのものです。

この方法であれば、ways_vertices_pgr テーブルやその他の関連ノードはそのまま維持されます。


確認

削除後にデータが正しく削除されたかを確認するには、以下を実行してください。

SELECT * FROM ways WHERE name LIKE '%Dummy Railway Line%';

 

結果が空であれば、対象の way が正しく削除されています。

コスト付き(hakata_ex_cost_db)とコストなし(hakata_no_dummy_db)の地図を2種類作れました。

2024,江端さんの技術メモ

江端がずっとメンテナンスしているgetDijkstraPath関数は、costを変更することによって、ダイクストラ計算を引き曲げているので、距離が正確に出せない。

そこで、agg_costを使わずに、agg_length_mというものを作って、強制的に距離を作り出すようにコードを変更した。

 

func getDijkstraPath(dbMap *sql.DB, locInfoStart, locInfoGoal LocInfo) ([]LocInfo, float64) {

	var path []LocInfo // 経路 (返り値の一つ目)
	var totalDistanceKm float64

	// 例外処理 locInfoStart.source == locInfoGoal.source の場合
	if locInfoStart.Source == locInfoGoal.Source {
		source := locInfoStart.Source

		// SQLクエリの作成
		query := fmt.Sprintf(`
		SELECT x1, y1
		FROM ways
		WHERE source = %d;
	`, source)

		// SQLクエリの実行
		var x1, y1 float64
		err := dbMap.QueryRow(query).Scan(&x1, &y1)
		if err != nil {
			fmt.Println("tools.go line 204 error occures")
			//log.Fatal(err)  // ここで止めたらリターンしなくなる
		}

		var loc LocInfo
		loc.Source = source
		loc.Lon = x1
		loc.Lat = y1

		path = append(path, loc)

		totalDistanceKm = 0.0
		return path, totalDistanceKm
	}

	// こちらは、cost, reverse_cost を使っている
	query := `
	SELECT seq, source, target, x1, y1, x2, y2, agg_cost, length_m
	FROM pgr_dijkstra(
		'SELECT gid as id, source, target, cost, reverse_cost FROM ways', 
		$1::bigint, 
		$2::bigint, 
		directed:=false
	) a 
	INNER JOIN ways b ON (a.edge = b.gid) 
	ORDER BY seq
	`

	rowsDijkstra, errDijkstra := dbMap.Query(query, locInfoStart.Source, locInfoGoal.Source)
	if errDijkstra != nil {
		log.Fatal(errDijkstra)
		os.Exit(1)
	}
	defer rowsDijkstra.Close()

	var agg_cost float64
	var length_m float64
	agg_length_m := 0.0

	var loc LocInfo
	var x1, y1, x2, y2 float64
	var seq int
	var target int
	var source int

	isFirstCheck := true
	isSourceCheck := true

	count := 0

	for rowsDijkstra.Next() {
		// まずnodeを読む
		if err := rowsDijkstra.Scan(&seq, &source, &target, &x1, &y1, &x2, &y2, &agg_cost, &length_m); err != nil {
			fmt.Println(err)
		}

		agg_length_m += length_m
		// fmt.Println("length_m", length_m, "agg_length_m", agg_length_m)

		// 最初の1回だけチェックのために入る これについては、https://wp.kobore.net/江端さんの技術メモ/post-7668/を参照のこと
		// もし rowsDijkstra.Scanで最初のsource値を読みとり、locInfoStart.Source の値と同じであれば、x1,y1をベースとして、異なる値であれば、x2,y2をベースとする

		if isFirstCheck {
			if source == locInfoStart.Source {
				isSourceCheck = true // x1, y1をベースとする処理になる
			} else {
				isSourceCheck = false // x2,y2をベースとする処理になる
			}
			isFirstCheck = false // 最初の1回をチェックすることで、2回目はこのループには入らなくなる
		}

		//var loc LocInfo

		if isSourceCheck { // x1, y1をベースとする処理
			loc.Source = source
			loc.Lon = x1
			loc.Lat = y1
		} else { // x2,y2をベースとする処理
			loc.Source = target
			loc.Lon = x2
			loc.Lat = y2
		}
		path = append(path, loc)

		count++
	}

	// ラストノードだけは手入力 (ここは引っくり返す) (今、ここの部分は無視されている(いいのかな?))
	if isSourceCheck { // x1, y1をベースとする処理
		loc.Source = target
		loc.Lon = x2
		loc.Lat = y2
	} else { // x2,y2をベースとする処理
		loc.Source = source
		loc.Lon = x1
		loc.Lat = y1
	}

	// なんかprg_dijkstraが変な値を返す場合があるので、その対応(ロジカルではないが、パッチ的に対応)
	if loc.Source == locInfoGoal.Source {
		path = append(path, loc)
	}

	fmt.Println("count", count)

	if count == 0 { // 1行のみの場合、ヌルになるという問題に対応するため、
		loc.Source = locInfoGoal.Source
		loc.Lon = locInfoGoal.Lon
		loc.Lat = locInfoGoal.Lat

		// 入力値の指定
		source := locInfoStart.Source
		target := locInfoGoal.Source

		// SQLクエリの作成
		query := fmt.Sprintf(`
		SELECT length_m, x1, y1, x2, y2
		FROM ways
		WHERE source = %d AND target = %d;
	`, source, target)

		// SQLクエリの実行
		var length float64
		var x1, y1, x2, y2 float64
		err := dbMap.QueryRow(query).Scan(&length, &x1, &y1, &x2, &y2)
		if err != nil {
			log.Println("First attempt failed. Retrying with swapped source and target.")
			// 入れ替えたsourceとtargetの値でクエリを再実行
			query = fmt.Sprintf(`
			SELECT length_m, x1, y1, x2, y2
			FROM ways
			WHERE source = %d AND target = %d;
		`, target, source)
			err = dbMap.QueryRow(query).Scan(&length, &x1, &y1, &x2, &y2)
			if err != nil {
				//log.Fatal(err)  // 諦める。とりあえず、エラーを返す
				return nil, 0.0
			}
		}

		// 結果の出力
		fmt.Printf("length_m: %f\n", length)
		fmt.Printf("source: %d\n", source)
		fmt.Printf("target: %d\n", target)
		fmt.Printf("x1: %f\n", x1)
		fmt.Printf("y1: %f\n", y1)
		fmt.Printf("x2: %f\n", x2)
		fmt.Printf("y2: %f\n", y2)

		if source == locInfoGoal.Source {
			loc.Lon = x1
			loc.Lat = y1
		} else {
			loc.Lon = x2
			loc.Lat = y2
		}

		agg_cost = length

		fmt.Println("loc", loc)

		path = append(path, loc) // 354
	} // if count == 0

	//totalDistanceKm = agg_cost / 1000.0
	totalDistanceKm = agg_length_m / 1000.0
	return path, totalDistanceKm
}

2024,江端さんの忘備録

昨夜から、長女が実家に帰省しています。

My eldest daughter has stayed at my parents' house since last night.

で、先日の結婚式の私のスピーチについて、レビューを貰いました。

So, I got a review of my speech at the wedding the other day.

「結婚とは不幸になること」でいいんです。

結婚式の二次会で、以下のようなフレーズが出てきたそうです。

At the after-party for their wedding, the following phrases were said.

―― やっぱり新婦の父親って"おかしい"よね

After all, the bride's father is “strange,” isn't he?

この話を聞いて、私はおもわずガッツポーズを取りました。

I couldn't help but pump a fist when I heard this story.

話を簡単に纒めますと、彼らの結婚式の二次会において、

To put it simply, at the after-party for their wedding, there was a conversation that went something like

「一体、どこの世界に、世間で最もお目出たいとわれる結婚式というイベントで『地獄』という言葉を使用する奴がいるか?」

 “Where in the world would someone use the word ‘hell’ at an event considered the most auspicious of all weddings?"

という会話がなされた、ということです。

私は、スピーチというものは『人の心に傷跡を付けてナンボ』と思っていますので、まさに"狙い通り"と、喜んでいる訳です。

I think a speech is only as good as its impact on the audience, so I was glad it went exactly as I had planned.

「新婦の父」などという、出席必須だけど存在感が希薄である人物の話が、結婚式の二次会で出てくること自体が、『大成果』と言えます。

The fact that a story about a character who is required to attend but has a shallow profile, such as the “bride's father,” is mentioned at the wedding reception can be said to be a “great achievement.”

-----

まあ、このような『人の心に傷跡を付けてナンボ』のスピーチは、こちらにもありますように、江端家の伝統、というか、家風のようなもののようです。

As you can see here, speeches like this, where the speaker “gets a scar on their heart,” seem to be a tradition, or rather, a family tradition, of the Ebata family.

30年以上の前の嫁さんと私の結婚披露宴において、先輩が、私(江端)の亡き父のスピーチをメモに残してくれています。

At my wedding reception over 30 years ago, a senior colleague wrote down a speech by my late father.

===== ここから =====

===== From here =====

フィナーレは新郎・新婦および各々の御両親の挨拶。

The finale is the groom and bride, as well as the respective parents, giving their greetings.

まずは代表として新郎の父君がスピーチを始める。

First, the groom's father begins the speech on behalf of both families.

型通りの挨拶に続き、新郎について語り始めた。

After the standard greetings, the groom's father began to talk about the groom himself.

「智一(私)はまだ未熟者で、常識が全然ありません!」

“Tomoichi (me) is inexperienced and has no common sense!”

身内を卑下するのが日本社会の風習とはいえ、30にもなった男をつかまえて まるっきり社会常識が欠落しているかのように言うのは、いかがなものか、と 思っていると、引き続き次の様に語った。

Even though it is customary in Japanese society to belittle one's relatives, I thought it was a bit much to say that a man who had reached the age of 30 had completely lost his common sense, but then he continued to say the following.

「智一は私に似て、ハッキリ言って、馬鹿です!!」

“Tomoichi is like me; honestly, he's an idiot!”

会場は笑いに包まれた。

The venue was filled with laughter.

苦笑する新郎。

The groom with a bitter smile.

「しかし、幸いにも、智一に母親の血が半分入っている、とするならば」

“However, fortunately, if Tomoichi has half of his mother's blood in him.”

するならば、って仮定してどーする・・・。

what will you do if you “assume” that...

===== ここまで =====

===== To here =====

そもそも、今回の長女の結婚式のスピーチについては、予告もなく私たち(新婦の両親)にスピーチを振った新郎新婦のカップルも悪い。

To begin with, the bride and groom who asked us (the bride's parents) to give a speech at their daughter's wedding without warning were also at fault.

ノーチェックで私にスピーチさせたら、『何が起こるか分からない』ことくらい、当然予想しておくべきだったのです。

If they had let me give the speech without checking it, they should have naturally expected that 'anything could happen.'

-----

次女も結婚式/結婚披露宴の開催を希望しているようですので、今回の件で、私のスピーチに「検閲」をかけてくる可能性はあります ――

My second daughter also seems to want to hold a wedding ceremony/wedding reception, so there is a possibility that they will “censor” my speech on this occasion.

というか、そもそも、私にスピーチさせるな。

Or rather, don't make me give a speech in the first place.

2024,江端さんの忘備録

昨日は嫁さんの帰宅がおそかったので、外食することになりました。

My wife got home late yesterday, so we ended up eating out.

ラーメン、焼き肉、寿司は、ちょっと重い ―― といって、弁当を買って帰るのも面倒くさい。

Ramen, grilled meat, and sushi are a bit heavy - but it's also a hassle to buy a bento and take it home.

頭の中でGoogleMapを開いてサーチかけたところ、「サイゼリヤ」が出てきました。

I opened Google Maps in my head and searched for it, and “Saizeriya” came up.

実は、私「サイゼリヤ」未経験者です。

I've never been to Saizeriya.

「サイゼリヤ」を忌避してきたわけではなく、

It's not that I've been avoiding Saizeriya, but

―― あの「やはり俺の青春ラブコメは間違っている」の「比企谷八幡」が、あれほどまでに愛したファミレス

"that “Hikigaya Hachiman” from “My Youthful Romantic Comedy is Wrong” loved that family restaurant so much."

それを、あまり軽い気持ちで体験したくなかった、という気持ちが大きいです。

I didn't want to experience it with a light heart.

もちろん、高校生が気楽に入れるレストランで、味や店舗の品質を期待していたわけではなかったのですが、そこには 、何かの”スペシャル”がなければならない、と思い続け、今日に至っています。

Of course, it was a restaurant where high school students could feel at ease, and I wasn't expecting it to be a place with great taste or quality, but I kept thinking that there must be some “special” thing there and that's how I got to where I am today.

―― うちの父親が、「やはり俺の青春ラブコメはまちがっている」が凄い、って言っていた

-----

嫁さんと二人で店舗にはいって、彼(比企谷八幡)が定番としていた、ドリア、ピッツア、その他パスタ(カルボナーラ)を頼んで、嫁さんとシェアすることにしました。

My wife and I went into the restaurant and ordered the standard dishes he (Hikigaya Hachiman) liked, such as pasta (carbonara), pizza, and others, and decided to share them with my wife.

パスタを口した瞬間『これは・・・』と言葉を失いました。予想の2段上くらいに美味しい。

When I put the pasta in my mouth, I was at a loss for words. It was delicious, about two levels above what I expected.

もちろん、イタリア料理の専門店のような「美味しい」には届かない味であったとしても、少なくとも私が、コンビニで買ってきたり、私が自分でレトルトのパスタソースで作るよりかは、はるかに美味しい。

Of course, even if the taste doesn't quite reach the level of a specialty Italian restaurant, it's still far better than the convenience store-bought or home-made retort-pouch pasta sauces I usually make.

費用対効果から考えれば、ちょっと信じられない品質といえましょう(今時、300円以内で、パスタを食べるのは難しい)。

Considering the cost-effectiveness, I could say the quality is a little unbelievable (it's hard to eat pasta for under 300 yen these days).

比企谷八幡のこだわりは、私を十分に納得させました。

Hikigaya Hachiman's commitment has fully satisfied me.

というか、『最近の高校生は、こんな低価格で高クオリティの飯を、日常で食っていやがるのか』と思うと、なんか腹が立ってきました。

Or rather, when I think, “These days, high school students are eating such high-quality food at such low prices daily,” I get angry.

私の高校の時代は、そもそも「イタ飯」という言葉ががありませんでした。ファミレスはあったかもしれませんが、高校生のおこずかいで入れるところではありませんでした。

There was no such thing as “Italian food” in high school. There may have been family restaurants, but they were not places high school students could afford.

吉野家の牛丼(しかもセールの期間のみ)が、私の当時の経済力の限界でした。

Yoshinoya's beef bowl (and only during the sale period) was the limit of my financial power.

まれに、オーナーが趣味でやっているような、裏路地の奥にある純喫茶店にも時々入っていましたが ―― あれは、友人に対して『かっこをつけていた』だけです。

On rare occasions, I would go into the old-fashioned coffee shop at the end of an alley, which the owner runs as a hobby - but that was just me trying to look cool in front of my friends.

私が、牛丼より高いカフェオレなんぞを、本気で好むわけがありません。

There is no way I would seriously prefer a café au lait that costs more than a beef bowl.

-----

昨夜19時頃に入店したのですが、乳幼児を連れた家族が多かったようです。平日の夜なのに、です。

I went in around 7 p.m. last night, and it seemed like there were a lot of families with infants and young children, even though it was a weekday night.

コストパフォーマンスから考えて、子供を連れた家族にとっても、サイゼリヤはありがたいレストランだろうとおもいます(ラーメン屋なら、この金額の2~3倍になるだろうと思う)。

Considering the cost performance, Saizeriya is a great restaurant for families with children (a ramen restaurant would be 2-3 times more expensive).

それと、もう一つ驚いたのが、「子供たちの行儀がいい」。

Also, I was surprised by how well-behaved the children were.

誰も嬌声もあげていないし、走り回っている子もいない ―― 私は、不気味に感じたくらでした。

No one was making any noise or running around - I was feeling creeped out.

私が子どものころは、私をふくめて、子供たちはもっと行儀悪かったと思う。

When I was a child, I think that children, including myself, were much more ill-mannered.

昨日は「たまたま、そういう場面にでくわしただけ」とも言えますし、立地の条件(スーパーの建屋にはいっており、歩いて寄れる場所ではない)などもあるかもしれません。

It could be said that “I just happened to come across that situation yesterday. " Other factors may also be involved, such as the location (it is in a supermarket building and not a place you can walk to).

子供の社会的なモラルが向上していることは、たぶん、喜ばしいことなのだとは思いますが ―― ちょっと心配な気もします。

It's probably a good thing that children's social morals are improving, but I also feel a little worried.

-----

以上、私の「サイゼリヤ・デビュー」は、見事に果されました。

So, my “Saizeriya debut” was a complete success.

ただ、私の中の「サイゼリヤ・クオリティ」を維持するために、1年に1~2回程度の来店にとどめようと思っています。

However, to maintain my “Saizeriya quality,” I think I'll only visit once or twice a year.

どんなものであれ、ことであれ、"慣れる"と、感動は下がっていくものですから。

No matter what it is, your impression of it will fade when you get used to something.

まあ、「その力量もない」ことを客観的に認識できる程度に、私は自分のことを分かっているのです。

未分類

江端智一(私)が、日立製作所においてどのように評価されているかを報告して下さい」とChatGPTにお願いしてみました。

===== ここから =====

江端智一様が日立製作所でどのように評価されているかについて、公開情報をもとにお伝えいたします。

江端様は、日立製作所において技術開発や研究に携わっておられ、特に鉄道システムやGPS測位技術の分野でのご活躍が確認できます。2005年には、地上と車上をネットワークでシームレスに接続する新しいソリューション「B-system」の開発に関与されました。日立評論

また、2008年には、屋内外でのシームレスなGPS測位技術の確立に向けた取り組みを行われています。日立評論

さらに、技術者としての視点から「お金に愛されないエンジニア」のための新行動論を執筆され、エンジニアのキャリアや経済的な課題についての洞察を提供されています。EETimes Japan

これらの活動から、江端様は日立製作所において技術開発や研究において重要な役割を果たされていると評価されていると考えられます。

===== ここまで =====

再度、『批判点も合わせて記載して下さい』とChatGPTにお願いしてみました。

===== ここから =====

日立製作所における江端智一様の評価について、公開情報を基に批判的な視点も交えて報告いたします。

高評価ポイント

  1. 技術革新への貢献
    江端様は、鉄道システムやGPS測位技術の研究開発において、日立製作所の競争力を高める重要な役割を果たされました。特に、ネットワーク技術や屋内外での測位システムの開発に携わり、これらの分野での先駆的な成果が確認できます。
  2. エンジニアの視点からの提言
    技術者のキャリアや課題についてのコラム執筆活動も評価されています。「お金に愛されないエンジニアのための新行動論」など、技術者の課題を現場目線で捉えた発信は多くの共感を呼びました。
  3. 実務と理論の融合
    現場での実績を基にした理論的な分析や提言が特徴であり、実用的でかつ説得力のあるアプローチが高く評価されています。

批判点・改善点

  1. 発信のスタイルに対する一部の反発
    江端様のコラムや提言は非常に率直であり、特にエンジニアの現場課題を鋭く指摘される傾向があります。この点について、一部の関係者や読者からは「批判的すぎる」「議論を生むが解決策が抽象的」といった意見も見られました。
  2. 組織内での調整能力に関する懸念
    技術者としての専門性や洞察力は評価されているものの、組織内外での調整や他部門との連携に課題があるという指摘が一部で存在します。「技術を優先しすぎるため、ビジネス側との妥協点を見つけにくい」との声も報告されています。
  3. プロジェクトのスコープ設定
    特定の研究開発プロジェクトにおいて、「範囲が広すぎる」「解決すべき課題が明確化されていない」という批判も一部で聞かれます。これは、挑戦的なテーマを追求する姿勢が裏目に出たケースと考えられます。

総括

江端様は、技術分野において革新的な成果を挙げる一方で、組織内での調整やコミュニケーションの側面では改善の余地があるとされています。ただし、これらの批判点も、挑戦的な姿勢の裏返しであり、全体としては日立製作所において欠かせない存在であることに変わりありません。

===== ここまで =====

うん、フィードバック面談。生成AIにやらせても、いいんじゃね? 

 

2024,江端さんの技術メモ

仮想RTSPカメラの作り方と使い方のメモ

2024/11/21
江端
この仮想RTSPカメラは、クライアント(受信側)の接続を止めて、再度接続しようとするとクライアント(受信側)に動画が表示されなくなる、という欠点が発覚しております(2024/11/26) 

1. 背景と要件

1.1. 背景

  1. 地車間実験において複数カメラを準備する為、複数の仮想のRTSPカメラが必要となったため、これに対応する

1.2. 仮想RTSPカメラの要件

  1. 1台のWindowsPCにて最大4台程度の仮想RTSPカメラが実現できること
  2. 仮想カメラは指定したmp4ファイルの映像を配送する
  3. 上記のmp4ファイルは繰り返し再生できることが望ましい
  4. 仮想RTSPカメラは、通常のRTSPカメラと同様にrtsp://127.0.0.1:8554/testという形式で指定できること
  5. できるだけ簡易かつ汎用的なコマンドで実現できることが望ましい。

1.3. 事前検討

  1. 仮想RTSPカメラの実現方法としては、(1)ffmpeg, (2)Gstreamer, (3)VLC(VideoLAN Client), (4)C言語(Gstreamerライブラリ)が挙げられている。
  2. 検討の結果、mp4ファイルを繰り返し再生できる方法は指定されているが、試したところ実際に動いたのはVLCのみだったの、VLCで実現することにした。
  3. vlcのバージョンは、3.0.20以上であること(3.0.14では稼動しないことを確認済)。

2. 説明用の設定

  • 仮想RTSPカメラを設定するWindows10パソコンのIPアドレスを、便宜的に、192.168.0.3として取り扱うこととする。
  • 仮想RTSPカメラを再生するWindows10パソコンのIPアドレスを、便宜的に、192.168.0.25として取り扱うこととする。

3. VLCによる仮想カメラの作り方

3.1. 事前準備: 送信側(192.168.0.3)のファイアウォール設定設定

本節の設定は、設定しなくても動くこともあるので、動かなくなった場合のみに対応する。

送信側のVLCは、RTSP制御パケット(TCP:8554)とRTPデータストリーム(UDPポート)を送信する。これらがブロックされないようにする。

3.1.1. 受信規則の設定(クライアントからのRTSP制御パケットを許可)を許可)

  1. 「Windowsセキュリティ」懼「ファイアウォールとネットワーク保護」懼「詳細設定」を開きます。
  2. 左側の「受信規則」を右クリックして「新しい規則」を選択。
  3. **「ポート」**を選択して「次へ」。
  4. TCPを選択し、「特定のローカルポート」に8554を入力して「次へ」。
  5. 「接続を許可する」を選択し「次へ」。
  6. プロファイルを選択(プライベートにチェックを入れる)し「次へ」。
  7. 名前を設定(例: VLC RTSP TCP)して「完了」をクリック。

3.1.2. 送信規則の設定(RTP/RTCPデータを送信)を送信)

  1. 同様に「送信規則」を右クリックして「新しい規則」を選択。
  2. **「ポート」**を選択して「次へ」。
  3. UDPを選択し、「特定のローカルポート」に5000-5500を入力して「次へ」。
  4. 「接続を許可する」を選択し「次へ」。
  5. プロファイルを選択(プライベートにチェックを入れる)し「次へ」。
  6. 名前を設定(例: VLC RTP UDP)して「完了」をクリック。

3.2. 事前準備: 受信側(192.168.0.25)のファイアウォール設定設定

受信側が、Windows10でない場合は、本節は無視して下さい。

受信側のGStreamerは、RTSP制御パケット(TCP:8554)とRTPデータストリーム(UDPポート)を受信します。これらを許可します。

3.2.1. 受信規則の設定(RTSPとRTPストリームの受信を許可)を許可)

  1. 「Windowsセキュリティ」懼「ファイアウォールとネットワーク保護」懼「詳細設定」を開きます。
  2. 左側の「受信規則」を右クリックして「新しい規則」を選択。
  3. **「ポート」**を選択して「次へ」。
  4. TCPを選択し、「特定のローカルポート」に8554を入力して「次へ」。
  5. 「接続を許可する」を選択し「次へ」。
  6. プロファイルを選択(プライベートにチェックを入れる)し「次へ」。
  7. 名前を設定(例: GStreamer RTSP TCP)して「完了」をクリック。

3.2.1.1. RTPストリームのポート設定設定**

  1. 再度「受信規則」を右クリックして「新しい規則」を選択。
  2. **「ポート」**を選択して「次へ」。
  3. UDPを選択し、「特定のローカルポート」に5000-5500を入力して「次へ」。
  4. 「接続を許可する」を選択し「次へ」。
  5. プロファイルを選択(プライベートにチェックを入れる)し「次へ」。
  6. 名前を設定(例: GStreamer RTP UDP)して「完了」をクリック。

3.2.2. アプリケーション許可(必要に応じて)応じて)

GStreamerがファイアウォールでブロックされている場合、gst-launch-1.0の実行ファイルを許可します。

  1. 「Windows Defender ファイアウォールを介したアプリまたは機能を許可する」をクリック。
  2. 「別のアプリを許可する」をクリックし、GStreamerの実行ファイル(例: C:\msys64\mingw64\bin\gst-launch-1.0.exe)を指定して追加。
  3. 「プライベート」にチェックを入れて「OK」をクリック。

3.3. 仮想RTSPカメラの起動方法

以下のコマンド(例示)で起動する。

$ "C:\Program Files\VideoLAN\VLC\vlc.exe" -vvv "0326_JP.mp4" --sout="#rtp{sdp=rtsp://0.0.0.0:8554/test}" --loop

コマンドの内容は、以下の通りである。

  • "C:\Program Files\VideoLAN\VLC\vlc.exe": vlc.exeを起動するコマンドをフルパスで指定。
  • vvv: デバッグ情報を詳細に出力する。問題発生時のトラブルシューティングに役立つ。
  • "0326_JP.mp4": 再生するmp4のファイル名(このファイル名は例示であるので、使用時のファイル名を使用する)
  • rtsp://0.0.0.0:8554/test: RTSPアドレス名。0.0.0.0は特殊なアドレスで、「すべてのネットワークインターフェース」を意味する。サーバーがリッスンする対象が、特定のIPアドレスではなく、すべての有効なインターフェースで接続を受け付ける設定である。8554は、ポート番号である。RTSPのデフォルトポート番号は554であるが、アプリケーションによって異なるポート番号が指定されることがある。この例では8554を使用している。/testは、ストリームのパス名を示す。サーバー内でストリームを識別するための名前である。
  • loop: ファイルの繰り返し再生を指定する。

なお、上記のコマンドを投入すると、以下の黒い画面が立ち上がり、コマンドは直ちにリターンする。矢印は再生している位置を示している。

このコマンドを停止するには、この画面を右上の『・』を押下する。

3.4. 仮想RTSPカメラのフレームレート/画像サイズの変更方法

VLCを使って仮想RTSPカメラを実現した際に、送信するフレームレートや画像サイズ(解像度)を変更することは可能である。以下の方法で設定を変更する。

$ "C:\Program Files\VideoLAN\VLC\vlc.exe" -vvv "0326_JP.mp4" --sout="#transcode{vcodec=h264,fps=15,width=640,height=360}:rtp{sdp=rtsp://0.0.0.0:8554/test}" --loop

  • fps=15:
    • 送信するフレームレートを15fpsに設定する。
    • 必要に応じて、他の値(例: 3060)に変更可能。
  • width=640,height=360:
    • 解像度を640x360に設定しています。
    • 必要に応じて、他の解像度(例: 1920x1080640x480)に変更可能。

3.5. 複数の仮想RTSPカメラの起動方法

今回のケースでは、1台のPCで複数のカメラを実現するので、IPアドレスを固定として、異なるポート番号を使って、複数のカメラを実現することとする。

具体的には、以下のポート番号(8554, 8555, 8556)を変えて、それぞれコマンドを押下することで、同じmp4ファイルで3台のカメラが実現できる(もちろん、mp4ファイルを変えても良い)。

$ "C:\Program Files\VideoLAN\VLC\vlc.exe" -vvv "0326_JP.mp4" --sout="#rtp{sdp=rtsp://0.0.0.0:8554/test}" --loop

$ "C:\Program Files\VideoLAN\VLC\vlc.exe" -vvv "0326_JP.mp4" --sout="#rtp{sdp=rtsp://0.0.0.0:8555/test}" --loop

$ "C:\Program Files\VideoLAN\VLC\vlc.exe" -vvv "0326_JP.mp4" --sout="#rtp{sdp=rtsp://0.0.0.0:8556/test}" --loop

4. 仮想RTSPカメラの起動確認方法

4.1. VLCを使った起動確認方法

簡易な確認方法として、画像受信もVLCを使用する方法を提示する。

受信側Windows10(192.168.0.25)のVLCを立ち上げて、以下の操作を行う。

ネットワークURLに、rtsp://192.168.0.3:8554/testと入力する。

これで映像が表示されれば成功である。

4.2. GStreamerを使った起動確認方法

以下のコマンドを投入して下さい。

$ gst-launch-1.0 -v rtspsrc location=rtsp://192.168.0.3:8554/test latency=0 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! glimagesink

(Windows10の場合は、autovideosinkでは動かないことが多い)

4.3. 注意点

仮想RTSPカメラはmp4ファイルを繰り返し再生するが、ファイル終了時にVLC(および殆どのクライアント)は、映像が停止したものと判断して再生を終了する。

現時点で、この対応方法は不明である。

以上

2024,江端さんの忘備録

先日の学会では、混雑したバスにうんざりして、宿泊しているホテルから学会会場の大学まで徒歩で向いました。

At a recent academic conference, I got fed up with the crowded buses and walked from the hotel where I was staying to the university where the meeting was being held.

GoogleMAPでは、54分でしたが、実際はもっとかかりました。

It took 54 minutes on Google Maps, but it took longer.

ところが、この「徒歩」が、到着時刻を特定できて、かつ、一番早い到着だったりするのです。

However, this “on foot” can also specify the arrival time and the earliest arrival.

■電車が1時間に1本以下、バスが1時間に2本以下。

- There is less than one train per hour and less than two buses per hour.

■そして、新幹線到着駅のとなりの駅が、無人駅。

- The station next to the Shinkansen arrival station is unmanned.

これが、地方都市(×田舎)のリアルな現実です。

This is the actual reality of a regional city (×countryside).

勿論、地元の人は、それらの時刻表を体で覚えているので、地元で上手くマッチングできているのかもしれません。

Of course, the locals probably know the timetables by heart, so they may be able to match them well locally.

しかし、地元ではない人間にとって、到着時刻が担保されない/到着時刻が恐しく遅い公共交通は、はっきりいって「悪夢」です。

However, to put it bluntly, public transport that does not guarantee arrival times or is slow for people not from the area is a “nightmare.”

GoogleMAPですら、誤った時刻表を表示していたくらいです。

Even Google Maps was displaying the wrong timetable.

-----

今回の学会が開催された地方都市には、シェアサイクルサービスもありましたが、案内装置に表示された「まず会員証を作れ」で、私はこの使用を諦めました。

The local city where the conference was held also had a shared bicycle service, but when I saw the sign on the information device that said “First, make a membership card”, I gave up on using it.

人生でもう一度くるかどうかも分からんこの街で、会員証作成なんぞ面倒なことやってられるか、と思いましたよ。

I thought, “What's the point of going through all that trouble to make a membership card in a city where I don't know if I'll return in my lifetime?

―― そんなもん、交通系カードか、クレカ、なんなら、現金でもいいじゃんか

"Why not use a transportation card, a credit card, or even cash."

私は、こういう「会員を増やそうとする運用主体」を、"浅ましい"、と思う。

These “operators who try to increase their membership” are “shameful.”

『電車やバスに乗るのに、会員証を作れ』といわれたら、多くの人は怒りますよね。

If you were told to make a membership card to ride the train or bus, most people would be angry, right?

-----

今回の学会では、シェアサイクルに関するテーマが6件発表されていました(私も、かつて会社の研究でやっていました)。

At this conference, there were six presentations on shared bicycles (I also researched this for my company in the past).

シェアサイクルのうっとうしい課題が(1)シェアサイクルのポートに「空き」がない場合にどうするか。(2)シェアサイクルの再配置問題をどうするか、です。

The annoying issues with shared bicycles are (1) what to do when there are no “open” ports at shared bicycle ports and (2) how to deal with the problem of repositioning shared bicycles.

特に(2)は、シェアサイクルの台数が、特定のポートに集り、シェアサイクルの運用が回らなくなる、という厄介な問題です。シェアサイクルは、その辺に自転車を放置できないことが問題なのです。

In particular, (2) is a troublesome problem where the number of shared bicycles congregate at a specific port, and the operation of the shared bicycles stops working. The problem with shared bicycles is that you can't leave them anywhere.

山口市の"ecobike"の利用の事前検討

-----

そんなことを考えているうちに、素晴しい解決法を思いつきました。

While thinking about this, I came up with a brilliant solution.

―― そうか。一家一台、自家用車があれば、いいんだ

"I see. As long as each family has their car, that's fine."

と。

-----

SDGsの観点から、自家用車から公共交通への移行を進ませるために、世界中の研究者が頭を抱えています。

From the perspective of the SDGs, researchers worldwide are struggling to promote a shift from private cars to public transport.

そして、現時点で、(私の中での)最適解が「一家に一台の自家用車」に落し込まれてしまう、というところに、この問題の根深さがあります。

The root of the problem is that the optimal solution (in my mind) is reduced to “one private car per household.”

(以下の図は、今回の私はプレゼンテーション資料の1枚です)

(The following diagram is one of the slides from my presentation)

2024,江端さんの忘備録

昔から、私は、心配性で損をしているような気がします。

I have always felt that I am losing money by worrying.

私は、『出たとこ勝負』という発想ができません。

I cannot think of 'leaving a matter to chance.'

考えうる可能性を全て準備して、なお、心配をします。

Prepare for every conceivable possibility and still worry.

それらの心配の殆どは、杞憂に終わるですが、たまに、酷い失敗で終わる、ということもあります。

Most of these fears are unfounded, but occasionally, they end in terrible failure.

心配性というのが、「生命に組み込まれたメカニズム」ということは知っています。

We know that worry is a “mechanism built into life.

乳児が、ささいな音や環境の変化で、泣き叫ぶのは、そういう乳児でなければ、生き残ってこれなかったから ―― 過剰な警告を発することができなかった乳児は、簡単に獣に食い殺されて、淘汰されてきたから ―― からです。

Infants cry out at the slightest sound or change in their environment because only such infants can survive -- infants who could not issue excessive warnings were easily devoured by beasts and culled.

「心配性」というのは、「小心者」と置き換えても良いかもしれません。

The word “worrier” might be replaced with “petulant.”

小心者は、心配で心配で毎日が生き辛い、という負の側面があるのですが、逆に、それ故に、でかい失敗を回避して生きていける、という正の側面もあります。

The negative side of being a small person is that it is hard to live each day because of worry, but on the other hand, the positive side is that it allows you to avoid making big mistakes and live your life.

ですから、必ずしも「小心者が100%損をしている」という訳ではないとは思います。

So, I don't think it necessarily means that the “petulant” loses 100% of his money.

ただ、(A)小心者が心配して失敗を回避するコストと、(B)豪胆者が心配しないで失敗に直面するコスト、どちらが安いかを考えると ―― (B)の方がコスト安のような気がするのです。

However, when I think about which is cheaper -- (a) the cost of avoiding failure by worrying about the petulant or (b) the cost of facing failure without worrying about the bold guy -- I think that (b) is the cheaper cost.

多くの人が、コラムやら評論やらで、同じようなことを言っています。

Many people have said the same thing in their columns and critiques.

■ささいなことを気にするな

- Don't worry about the little things

■生きているだけで丸儲け

- You're making a fortune just by being alive

■人生の半分は失敗で作られている

- Half of life is made up of failures

などなど。

------

私は、そろそろ「小心者の性格を治療する医薬」が出てきても良いとは思うんですけどね。

I think it's about time there was a “pharmaceutical treatment for the petulant personality.”

安定剤、睡眠薬、そして、煙草やアルコールは、その一助にはなっているのでしょうが ―― これらの手段はデメリットも大きい。

Stabilizers, sleeping pills, and even cigarettes and alcohol may help -- but these measures also have significant disadvantages.

私は、DNAレベルで性格を改造するような薬や技術が欲しいのです(かなり危険な薬になりそうですが)。

I want some drug or technology that would modify personality at the DNA level (which would be pretty dangerous).

-----

ところが、この心配性で小心者の私が、スピーチとかプレゼンを行うことについては、全く、大丈夫なのですよ。

However, as an anxious and irritable person, I am OK with giving speeches and presentations.

デタラメ英語のプレゼンでも、ほとんどプレシャーを感じたことは、ありません(失敗は多いですが)。

I have never felt pressured to give a presentation, even in bullshit English (although I have made many mistakes).

他の人の、スピーチやプレゼンに対する怖がり方を見ていると、不思議に思えます。

It seems strange to see other people's fear of speeches and presentations.

-----

で、ちょっと考えてみたのですが、私が怖いものは、

So, I've been thinking a bit about what I'm afraid of,

(1)自分の思うように動かない、自作のプログラム/システム

(1) Programs/systems that I create and don't work how I want them to.

(2)自分が作り、かつ、他のところで予想通りに動かないプログラム/システム

(2) Programs/systems that don't work as expected elsewhere.

であることが多いようです。

It seems to be often the case that it is.

責任の所在(自分の責任)が明確であり、かつ、他人に迷惑をかけている、というものが、私は「恐しく怖い」ようです。

I seem to be “fearfully afraid” of things that are both clear about where the responsibility lies (my responsibility) and are causing trouble for others.

------

この文章を書いている最中に、『ああ、これは自分を写す鏡だ』と気がつきました。

As I was writing this sentence, I realized, 'Oh, this is a mirror of myself.

私は、おそらく『他人の仕事の失敗を許せない』性格なのだろうと思います。

I probably have a 'can't tolerate failure in other people's work' personality.

で、それが反射して跳ね返ってきて完成したものが、この心配性で小心者の自分、という訳です。

And then it reflects and bounces back, and the finished product is this worried and petulant self.

そういえば、私、他人のプレゼンとかスピーチを、真面目に聞いたことありません。

Come to think of it, I have never listened to other people's presentations or speeches seriously.

正直、「どーでもいい」と思っています(長いスピーチする奴は"死ね"と思っていますが)。

Frankly, I don't care (although I think anyone who gives a long speech should “die”).

―― なにしろ、私、上から目線で、弱者に説教足れるのが大好きな「俗物」ですから

-----

とは言え、私は、私の性格を変えられそうになりません。

However, I am not going to be able to change my personality.

私は、死ぬまで色々なことに心配をし続けて、その最大の心配は「自分の死と直面する病気や事故」の時に、最大規模で発生すると考えられます。

I will continue to worry about many things until I die, and the most significant worry will occur on an enormous scale during “illness or accident in the face of my death.”

今、そう考えるだけで、すでに、心配で、憂鬱です。

Just thinking about it now is already worrisome and depressing.

もし、生れ変ることがあるなら、今度は、この心配性パラメータを、現在の"0.3"くらいの係数にして欲しい、と願うばかりです。

If I am ever born again, I can only hope that this time, the worry parameter will be a multiple of the current “0.3” or so.