2024,江端さんの技術メモ

これからGO言語で構造体を使い倒さねばならない私(江端)が、これから何度でもハマるような気がするので、わざわざ簡単なプログラムを作って、今後の自分の為にメモを残す。

agentsスライスの要素を変更しても、その変更が反映されない理由として、agent変数が値渡しである可能性があります。Goでは、スライスやマップなどのリファレンスタイプを使わない限り、変数は値渡しされます。

具体的には、以下のようなコードでは、agent変数はスライスagentsの要素をコピーしたものであり、変更はagentsスライス自体には反映されません。

 

重要なポイントは、

"for i, agent := range agents {" は表示するだけなら問題はないが、書き込みはできず、

" for i := range agents {
          agent := &agents[i] // この1行が滅茶苦茶重要"
としないと、書き込みが反映されない、ということであり、変更点は、以下のようにforループ内でagentをポインタとして扱うことである。

 

また表示の際にも、例えば1000番目の構造体のエージェントだけを表示したいのであれば、

i := 1000
	if i < len(agents) {  // これは構造体の数を越えていないかをチェックする
		agent := &agents[i]
この1行が滅茶苦茶重要"
		fmt.Printf("hh_id:%d idv_id:%d\n", agent.hh_id, agent.idv_id)
		fmt.Printf("Agent %d: q1=%d, q2t=%d, q31=%d, q32=%d, q33=%d, q34=%d, q41a=%d, q42a=%d, q43a=%d, q44a=%d, q45a=%d, q46a=%d, q47a=%d, q41e=%d, q42e=%d, q43e=%d, q44e=%d, q45e=%d, q46e=%d, q47e=%d, q10=%d, q13=%d, q14=%d, no_answer=%d\n",
			i, agent.q1, agent.q2t, agent.q31, agent.q32, agent.q33, agent.q34,
			agent.q41a, agent.q42a, agent.q43a, agent.q44a, agent.q45a, agent.q46a, agent.q47a,
			agent.q41e, agent.q42e, agent.q43e, agent.q44e, agent.q45e, agent.q46e, agent.q47e,
			agent.q10, agent.q13, agent.q14, agent.no_answer)

		for _, trip := range agent.trip {
			fmt.Printf("trip: {id:%d act_id:%d trip_id:%d day:%d origin:%s destination:%s ox:%.6f oy:%.6f dx:%.6f dy:%.6f m_ox:%.6f m_oy:%.6f m_dx:%.6f m_dy:%.6f dep_area:%s arr_area:%s dep_time:%s m_dep_time:%s arr_time:%s m_arr_time:%s stay_time:%.2f traffic:%s next_id:%d category:%d}\n",
				trip.id, trip.act_id, trip.trip_id, trip.day, trip.origin, trip.destination, trip.ox, trip.oy, trip.dx, trip.dy, trip.m_ox, trip.m_oy, trip.m_dx, trip.m_dy,
				trip.dep_area, trip.arr_area, trip.dep_time.Format("15:04:05"), trip.m_dep_time.Format("15:04:05"), trip.arr_time.Format("15:04:05"), trip.m_arr_time.Format("15:04:05"), trip.stay_time.Hours(), trip.traffic, trip.next_id, trip.category)
		}

以下は、その考え方を簡易に表現したもの

 

普通の構造体の取扱は、こんな感じでいい。

// G:\home\ebata\tomioka3B\src\others\main85.go

package main

import (
	"errors"
	"fmt"
)

// Trip構造体の定義
type Trip struct {
	id      int
	act_id  int
	trip_id int
	day     int
}

// Agent構造体の定義
type Agent struct {
	hh_id     int
	idv_id    int
	trip      []Trip
	sex       int
	no_answer int
}

// getGenderメソッドの定義
func (a Agent) getGender() (string, error) {
	switch a.sex {
	case 1:
		return "女性", nil
	case 2:
		return "男性", nil
	case 3:
		return "その他(未回答)", nil
	default:
		return "", errors.New("invalid sex value")
	}
}

func main() {
	// エージェントを5個生成
	agents := make([]Agent, 5)
	for i := 0; i < 5; i++ {
		agents[i] = Agent{
			hh_id:  i + 1,
			idv_id: i + 1,
			sex:    (i % 3) + 1, // 1, 2, 3をループ
			trip: []Trip{
				{id: 1, act_id: 10, trip_id: 100 + i, day: 1},
				{id: 2, act_id: 20, trip_id: 200 + i, day: 2},
			},
		}
	}

	// 各エージェントの性別とTrip情報を表示
	for i, agent := range agents {
		gender, err := agent.getGender()
		if err != nil {
			fmt.Printf("Agent %d: Error: %v\n", i+1, err)
		} else {
			fmt.Printf("Agent %d: Gender: %s\n", i+1, gender)
		}
		for _, trip := range agent.trip {
			fmt.Printf("\tTrip ID: %d, Act ID: %d, Trip ID: %d, Day: %d\n", trip.id, trip.act_id, trip.trip_id, trip.day)
		}
	}
}

出力結果
$ go run main85.go
Agent 1: Gender: 女性
Trip ID: 1, Act ID: 10, Trip ID: 100, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 200, Day: 2
Agent 2: Gender: 男性
Trip ID: 1, Act ID: 10, Trip ID: 101, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 201, Day: 2
Agent 3: Gender: その他(未回答)
Trip ID: 1, Act ID: 10, Trip ID: 102, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 202, Day: 2
Agent 4: Gender: 女性
Trip ID: 1, Act ID: 10, Trip ID: 103, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 203, Day: 2
Agent 5: Gender: 男性
Trip ID: 1, Act ID: 10, Trip ID: 104, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 204, Day: 2

このプログラムの後ろに、Agent 4を変更するプログラムを追加したい、とする。

Agent 4は
(1)hh_idを1000, idv_idを1001, sexを2、no_answerを1
(2)
Trip ID: 123, Act ID: 456, Trip ID: 789, Day: 1
Trip ID: 321, Act ID: 654, Trip ID: 987, Day: 2
とするプログラムは以下のようになる。

 

package main

import (
	"errors"
	"fmt"
)

// Trip構造体の定義
type Trip struct {
	id      int
	act_id  int
	trip_id int
	day     int
}

// Agent構造体の定義
type Agent struct {
	hh_id     int
	idv_id    int
	trip      []Trip
	sex       int
	no_answer int
}

// getGenderメソッドの定義
func (a Agent) getGender() (string, error) {
	switch a.sex {
	case 1:
		return "女性", nil
	case 2:
		return "男性", nil
	case 3:
		return "その他(未回答)", nil
	default:
		return "", errors.New("invalid sex value")
	}
}

func main() {
	// エージェントを5個生成
	agents := make([]Agent, 5)
	for i := 0; i < 5; i++ {
		agents[i] = Agent{
			hh_id:  i + 1,
			idv_id: i + 1,
			sex:    (i % 3) + 1, // 1, 2, 3をループ
			trip: []Trip{
				{id: 1, act_id: 10, trip_id: 100 + i, day: 1},
				{id: 2, act_id: 20, trip_id: 200 + i, day: 2},
			},
		}
	}

	// 各エージェントの性別とTrip情報を表示
	for i, agent := range agents {
		gender, err := agent.getGender()
		if err != nil {
			fmt.Printf("Agent %d: Error: %v\n", i+1, err)
		} else {
			fmt.Printf("Agent %d: Gender: %s\n", i+1, gender)
		}
		for _, trip := range agent.trip {
			fmt.Printf("\tTrip ID: %d, Act ID: %d, Trip ID: %d, Day: %d\n", trip.id, trip.act_id, trip.trip_id, trip.day)
		}
	}

	// Agent 4を変更
	agentIndex := 3
	if agentIndex < len(agents) {
		agents[agentIndex] = Agent{ // for i, agent := range agents のagentに上書きしても反映されない
			hh_id:     1000,
			idv_id:    1001,
			sex:       2,
			no_answer: 1,
			trip: []Trip{
				{id: 123, act_id: 456, trip_id: 789, day: 1},
				{id: 321, act_id: 654, trip_id: 987, day: 2},
			},
		}
	}

	// 変更後のエージェント情報を表示
	fmt.Println("\nAfter modification:")
	for i, agent := range agents {
		gender, err := agent.getGender()
		if err != nil {
			fmt.Printf("Agent %d: Error: %v\n", i+1, err)
		} else {
			fmt.Printf("Agent %d: Gender: %s\n", i+1, gender)
		}
		fmt.Printf("Agent %d: hh_id:%d, idv_id:%d, no_answer:%d\n", i+1, agent.hh_id, agent.idv_id, agent.no_answer)
		for _, trip := range agent.trip {
			fmt.Printf("\tTrip ID: %d, Act ID: %d, Trip ID: %d, Day: %d\n", trip.id, trip.act_id, trip.trip_id, trip.day)
		}
	}
}

出力結果
tomoi@DESKTOP-1QS7OI7 MSYS /g/home/ebata/tomioka3B/src/others
$ go run main85.go
Agent 1: Gender: 女性
Trip ID: 1, Act ID: 10, Trip ID: 100, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 200, Day: 2
Agent 2: Gender: 男性
Trip ID: 1, Act ID: 10, Trip ID: 101, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 201, Day: 2
Agent 3: Gender: その他(未回答)
Trip ID: 1, Act ID: 10, Trip ID: 102, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 202, Day: 2
Agent 4: Gender: 女性
Trip ID: 1, Act ID: 10, Trip ID: 103, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 203, Day: 2
Agent 5: Gender: 男性
Trip ID: 1, Act ID: 10, Trip ID: 104, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 204, Day: 2

After modification:
Agent 1: Gender: 女性
Agent 1: hh_id:1, idv_id:1, no_answer:0
Trip ID: 1, Act ID: 10, Trip ID: 100, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 200, Day: 2
Agent 2: Gender: 男性
Agent 2: hh_id:2, idv_id:2, no_answer:0
Trip ID: 1, Act ID: 10, Trip ID: 101, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 201, Day: 2
Agent 3: Gender: その他(未回答)
Agent 3: hh_id:3, idv_id:3, no_answer:0
Trip ID: 1, Act ID: 10, Trip ID: 102, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 202, Day: 2
Agent 4: Gender: 男性
Agent 4: hh_id:1000, idv_id:1001, no_answer:1
Trip ID: 123, Act ID: 456, Trip ID: 789, Day: 1
Trip ID: 321, Act ID: 654, Trip ID: 987, Day: 2
Agent 5: Gender: 男性
Agent 5: hh_id:5, idv_id:5, no_answer:0
Trip ID: 1, Act ID: 10, Trip ID: 104, Day: 1
Trip ID: 2, Act ID: 20, Trip ID: 204, Day: 2

2024,江端さんの技術メモ

TC(Traffic Controller)で、帯域5M、パケットロス10%、遅延1000msを セットするコマンドを教えて下さい

# qdiscの設定をクリア
sudo tc qdisc del dev eth0 root

# トークンバケットフィルター (TBF) を使用して帯域幅を制限
sudo tc qdisc add dev eth0 root tbf rate 5mbit burst 10kb latency 50ms

# ネットエミュレーション(netem)を使用して遅延とパケットロスを追加 sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 1000ms loss 10%

TC(Traffic Controller)のコマンドの一つとして使われている"latency"と"delay"の違いについて教えて下さい。

latency

"latency" は、トークンバケットフィルター (TBF) などのキューイングディシプリン(qdisc)で使用されます。ここでの "latency" は、バッファ内のパケットが許可される最大遅延時間を示します。つまり、指定されたバッファサイズ(burst)が満たされている場合に、パケットがそのバッファ内にどれだけ長く滞留できるかを示します。

delay

"delay" は、ネットエミュレーション(netem)で使用され、パケットに対して指定された遅延を追加します。この遅延は、ネットワークの遅延やラグをシミュレートするために使用されます。

まとめ

  • latency: TBF などのキューイングディシプリンにおいて、バッファ内での最大滞留時間を指定します。パケットの滞留時間が指定された latency を超えると、そのパケットはドロップされる可能性があります。バッファ内の滞留時間であり、ネットワーク全体の遅延を反映するものではありません。
  • delay: netem などで使用され、パケットに対して指定された遅延を直接追加します。ネットワーク全体の遅延やラグをシミュレートするために使用されます。

以上

 

2024,江端さんの技術メモ

type agent_od_2018_harugakkai struct {
	id      int
	hh_id   int
	idv_id  int
	act_id  int
	trip_id int
	day     int

	testtest float64

	origin      string // 自宅
	destination string // 病院

	ox float64
	oy float64
	dx float64
	dy float64

	m_ox float64 // ポリゴン境界補正後のox
	m_oy float64 // ポリゴン境界補正後のoy
	m_dx float64 // ポリゴン境界補正後のdx
	m_dy float64 // ポリゴン境界補正後のdy

追加のm_ox、m_oy、m_dx、m_dyが反映されず(というか、vscodeがエラーといってくる)ので、頭を抱えていましたが、どうやら、同じディレクトリにある別プログラムの定義をひっぱってきているようです。

同様に、メソッドも、無関係なプログラムをひっぱってこられて、VSCode上では警告の嵐になります。

ですので、短かいテストプログラムと言えども、面倒くさいですが、別のディレクトリを切って、そこでテストしなければならないようです。(VScodeは文句言うけど、たぶん、コンパイル/ビルドは通ると思います)。

# 実にもったいない時間の消費をしてしまいました。

 

 

2024,江端さんの技術メモ

ポインタと値の操作: item がリスト内の要素をポインタ経由で取得している場合、item を変更しても元のリストの要素が変更されることがありますが、それ以外の場合はそのような自動的な反映は行われません。必要に応じて、&item を使用してポインタ経由でアクセスし、リスト内の要素を直接変更します。

 

スライスと範囲ループの挙動: Go言語では、for range ループで取得した item は元のスライスの要素のコピーです。これにより、item を直接変更しても元のリストの要素に反映されません。そのため、ポインタ経由でアクセスして変更する必要があります。

失敗例

var estimatedStartTime time.Time
			var estimatedMovingTime time.Duration
			var estimatedStayTime time.Duration

			for i, item := range list {

				if i == 0 {
					estimatedStartTime = estimated_Start_Time(data, item.destination) // 出発時刻(リアル時間)
					fmt.Println("i=0のitem.destination:", item.destination)
					fmt.Println("i=0のestimatedStartTime:", estimatedStartTime)
					item.dep_time = estimatedStartTime // 時刻 (記録用)
					fmt.Println("in i=0  item.dep_time:", item.dep_time)
				} else {
					item.dep_time = estimatedStartTime.Add(estimatedMovingTime + estimatedStayTime)
				}

				fmt.Println("===================>", item.dep_time)

				estimatedMovingTime = estimated_Moving_Time(item.ox, item.oy, item.dx, item.dy) // 移動時間(間隔)
				fmt.Println("estimatedMovingTime:", estimatedMovingTime)

				estimatedStayTime = estimated_Stay_Time(data, item.destination) // 滞在時間(間隔)
				fmt.Println("estimatedStayTime:", estimatedStayTime)

				// item.dep_time = estimatedStartTime // 時刻 (記録用)
				item.stay_time = estimatedStayTime // 滞在時間(間隔) (記録用)


					if i+1 < len(list) {
						fmt.Println("in 558", estimatedStartTime, item.dep_time)
						nextItem := &list[i+1]
						nextItem.dep_time = estimatedStartTime.Add(estimatedMovingTime + estimatedStayTime) // 次の出発時刻 = 現在の出発時刻 + 移動時間
						fmt.Println("After nextItem.dep_time:", nextItem.dep_time)
						fmt.Println("in 562", estimatedStartTime, item.dep_time)
					}


				//fmt.Println("in 565", estimatedStartTime, item.dep_time)

			}

			for i, item := range list {
				fmt.Println(i, "item.dep_time:", item.dep_time)
				fmt.Println(i, "item.stay_time:", item.stay_time)
				fmt.Println(i, "item:", item)
				//fmt.Println(i, "item.dep_time:", item.dep_time.Format("2006-01-02 15:04:05"))
			}

成功例

var estimatedStartTime time.Time
		var estimatedMovingTime time.Duration
		var estimatedStayTime time.Duration

		for i := range list {
			if i == 0 {
				estimatedStartTime = estimated_Start_Time(data, list[i].destination)
				fmt.Println("i=0のitem.destination:", list[i].destination)
				fmt.Println("i=0のestimatedStartTime:", estimatedStartTime)
				list[i].dep_time = estimatedStartTime
				fmt.Println("in i=0  item.dep_time:", list[i].dep_time)
			} else {
				// 前のアイテムの出発時刻に移動時間と滞在時間を加えて計算
				list[i].dep_time = list[i-1].dep_time.Add(estimatedMovingTime + estimatedStayTime)
			}

			// 移動時間と滞在時間を計算する
			estimatedMovingTime = estimated_Moving_Time(list[i].ox, list[i].oy, list[i].dx, list[i].dy)
			fmt.Println("estimatedMovingTime:", estimatedMovingTime)

			estimatedStayTime = estimated_Stay_Time(data, list[i].destination)
			fmt.Println("estimatedStayTime:", estimatedStayTime)

			// 滞在時間を記録用に設定する
			list[i].stay_time = estimatedStayTime

			fmt.Println("===================>", list[i].dep_time)
		}

		for i := range list {
			fmt.Println(i, "item.dep_time:", list[i].dep_time)
			fmt.Println(i, "item.stay_time:", list[i].stay_time)
			fmt.Println(i, "item:", list[i])
		}
	}

そんな仕様、知るかーーーー

2024,江端さんの技術メモ

gst-launch-1.0 rtspsrc location=rtsp://cam:Cam12345@192.168.0.10/Src/MediaInput/stream_1 latency=0 ! rtph264depay ! avdec_h264 ! videoconvert ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=5/1 ! x264enc bitrate=1700 speed-preset=ultrafast tune=zerolatency key-int-max=1 ! mpegtsmux ! srtserversink uri = \"srt://192.168.101.10:38089\" latency=500
を実施するためだけのプログラムをGO言語で作成してください

package main

import (
	"fmt"
	"os"

	"github.com/go-gst/go-glib/glib"
	"github.com/go-gst/go-gst/gst"
)

func main() {
	fmt.Println("starting.....")

	// gstreamer初期化処理
	gst.Init(&os.Args)

	// メインループ生成
	mainLoop := glib.NewMainLoop(glib.MainContextDefault(), false)

	// パイプラインの要素を生成
	source, _ := gst.NewElement("rtspsrc")
	depay, _ := gst.NewElement("rtph264depay")
	decoder, _ := gst.NewElement("avdec_h264")
	convert, _ := gst.NewElement("videoconvert")
	scale, _ := gst.NewElement("videoscale")
	rate, _ := gst.NewElement("videorate")
	filter1, _ := gst.NewElement("capsfilter")
	filter2, _ := gst.NewElement("capsfilter")
	encorder, _ := gst.NewElement("x264enc")
	mux, _ := gst.NewElement("mpegtsmux")
	sink, _ := gst.NewElement("srtsink")

	// 各要素のプロパティを設定
	source.SetProperty("location", "rtsp://cam:Cam12345@192.168.0.10/Src/MediaInput/stream_1")
	source.SetProperty("latency", 0)
	filter1.SetProperty("caps", gst.NewCapsFromString("video/x-raw,width=640,height=360"))
	filter2.SetProperty("caps", gst.NewCapsFromString("video/x-raw,framerate=5/1"))
	encorder.SetProperty("bitrate", 1700)
	encorder.SetProperty("speed-preset", "ultrafast")
	encorder.SetProperty("tune", "zerolatency")
	encorder.SetProperty("key-int-max", 1)
	sink.SetProperty("uri", "srt://192.168.101.10:38089")
	sink.SetProperty("latency", 500)

	// パイプラインを生成して要素を追加
	pipeline, _ := gst.NewPipeline("video_player")
	pipeline.AddMany(source, depay, decoder, convert, scale, rate, filter1, filter2, encorder, mux, sink)
	gst.ElementLinkMany(depay, decoder, convert, scale, rate, filter1, filter2, encorder, mux, sink)

	// 動的パッドのリンク
	source.Connect("pad-added", func(element *gst.Element, pad *gst.Pad) {
		pad.Link(depay.GetStaticPad("sink"))
	})

	// パイプラインメッセージ読取
	pipeline.GetPipelineBus().AddWatch(func(msg *gst.Message) bool {
		switch msg.Type() {
		case gst.MessageEOS: // end-of-streamを受信したらパイプラインを停止
			pipeline.BlockSetState(gst.StateNull)
			mainLoop.Quit()
		case gst.MessageError: // エラーメッセージはFatalにする
			err := msg.ParseError()
			fmt.Println("ERROR:", err.Error())
			if debug := err.DebugString(); debug != "" {
				fmt.Println("DEBUG:", debug)
			}
			mainLoop.Quit()
		default:
			// 受信メッセージの表示
			fmt.Println(msg)
		}

		return true
	})

	// パイプライン開始
	pipeline.SetState(gst.StatePlaying)

	// メインループ開始
	mainLoop.Run()
}

2024,江端さんの技術メモ

C言語を使えて、GStreamerが使えて、GO言語を使えて、CGOが使える環境を作っています。

(1)Windowsの方のmsys2とGStreamerのパッケージを削除
Windowsの方のC言語、GStreamerはコンフリクトするので削除しますが、GO言語は、別のタスク(大学の方のシミュレータ)があるので、削除できませんでした。
という訳で、MSYS2の環境を、Windowsの方と切り離して運用するという覚悟ができました。

(2)C:の容量が小さいので、G:\の方にパッケージを分離していたのですが、これをやると、全く動かなくなるので、C:\msys2の配下に勝手に作成される、/c/msys64/home/tomoi/の直下でプログラムの作成をすることにしました。

これ、/usr/local/binの配下に/home/ebataを作るような気持ち悪さがあるのですが、今回は稼動が最優先です。

MSYS2のインストール

  1. MSYS2公式サイトからインストーラをダウンロードします。
  2. インストーラを実行し、画面の指示に従ってMSYS2をインストールします。

2. MSYS2の初期設定

  1. MSYS2ターミナルを起動: MSYS2 MSYSショートカットを使用してMSYS2ターミナルを起動します。
  2. パッケージデータベースと基本パッケージの更新: 以下のコマンドを順番に実行して、パッケージデータベースと基本パッケージを更新します。

    sh

    pacman -Syu

    初回のアップデートが完了したら、ターミナルを一度閉じて再起動します。

  3. 再度更新を実行: ターミナルを再起動後、再度以下のコマンドを実行します。

    sh

    pacman -Syu

3. MinGW-w64のインストール

  1. MinGW-w64ツールチェインのインストール: MSYS2 MinGW 64-bitショートカットを使用してMSYS2ターミナルを起動し、以下のコマンドを実行します。

    sh

    pacman -S mingw-w64-x86_64-toolchain

    これにより、GCC、G++、およびその他の開発ツールがインストールされます。

4. 環境変数の設定

MinGW-w64のバイナリにアクセスするために、環境変数PATHを設定します。

  1. ~/.bashrcファイルの編集: MSYS2ターミナルで~/.bashrcファイルを開きます。

    sh

    nano ~/.bashrc
  2. PATHの設定: 以下の行を追加して保存します。

    sh

    export PATH="/mingw64/bin:$PATH"
  3. 設定の反映: 設定を反映させるために、ターミナルを再起動するか、以下のコマンドを実行します。

    sh

    source ~/.bashrc

5. GStreamerのインストール

  1. GStreamerのパッケージのインストール: MSYS2 MinGW 64-bitショートカットを使用してMSYS2ターミナルを起動し、以下のコマンドを実行します。

    sh

    pacman -S mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad mingw-w64-x86_64-gst-plugins-ugly

    pacman -S mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad mingw-w64-x86_64-gst-libav

6. 確認とテスト

  1. GCCの動作確認: GCCが正しくインストールされているか確認します。

    sh

    gcc --version
  2. 簡単なCプログラムの作成とコンパイル: 簡単なCプログラムを作成してコンパイルします。

    sh

    nano test.c

    以下の内容を入力します。

    c

    #include <stdio.h>

    int main() {
    printf("Hello, World!\n");
    return 0;
    }

    ファイルを保存してNanoエディタを閉じた後、コンパイルします。

    sh

    gcc test.c -o test.exe

    コンパイルが成功したら、実行します。

    sh

    ./test.exe
  3. GStreamerの動作確認: GStreamerが正しくインストールされているか確認します。

    sh

    gst-launch-1.0 --version

    簡単なGStreamerパイプラインを実行して動作確認します。

    sh

    gst-launch-1.0 videotestsrc ! autovideosink

とうぜん 、ここまですんなりできた訳ではありませんが、取り敢えず私が思い出せる程度の情報を載せてあります。

-----

https://github.com/go-gst/go-gst

から、/home/tomoi/go/srcで、 git clone https://github.com/go-gst/go-gst をして、/home/tomoi/go/src/go-gst を作って、

に張ってあったプログラムを、main.goでセーブしたのち、

go run main.go videotestsrc ! glimagesink

で、

と、

が、表われることを確認。

なにがどうなっているのかは、サッパリ分からないが、とりあえず、GoからGstreamerが動いたことは確認できた。

以上

なんか、サラっと書くと自分でも腹たつなぁ。10時間以上はかかったんだけどなぁ

2024,江端さんの技術メモ

Windows10に、GStreamerの1.24をインストール(フルインストールを選ぶこと)をしたのですが、定番の、

$ gst-launch-1.0.exe videotestsrc ! autovideosink
Use Windows high-resolution clock, precision: 1 ms
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Got context from element 'autovideosink0': gst.d3d11.device.handle=context, device=(GstD3D11Device)"
\(GstD3D11Device\)\ d3d11device2", adapter=(uint)0, adapter-luid=(gint64)41376, device-id=(uint)1042
, vendor-id=(uint)32902, hardware=(boolean)true, description=(string)"Intel\(R\)\ HD\ Graphics\ 4600
";
ERROR: from element /GstPipeline:pipeline0/GstAutoVideoSink:autovideosink0/GstD3D11VideoSink:autovid
eosink0-actual-sink-d3d11video: Cannot create converter
Additional debug info:
Failed to prepare d3d11window
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
ERROR: from element /GstPipeline:pipeline0/GstVideoTestSrc:videotestsrc0: Internal data stream error
.
Additional debug info:
../libs/gst/base/gstbasesrc.c(3177): gst_base_src_loop (): /GstPipeline:pipeline0/GstVideoTestSrc:vi
deotestsrc0:
streaming stopped, reason error (-5)
ERROR: pipeline doesn't want to preroll.
Freeing pipeline ...

となります。別のWindows BOXでも、先日も経験して、青ざめていました。

結果として、

$ gst-launch-1.0 videotestsrc ! glimagesink

とすれば動きます。

autovideosinkが動かん、っていうのは、結局分かっていませんが、これは困りものです。

以下自分用メモ

-UDP通信の実験

-受信側

-gst-launch-1.0 videotestsrc ! x264enc ! rtph264pay ! udpsink host=192.168.101.10 port=38089
(ローカルの場合、host=127.0.0.1とする.  host=localhost は動かない)

-送信側

-gst-launch-1.0 udpsrc port=38089 caps="application/x-rtp,media=video,encoding-name=H264,payload=96" ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! glimagesink

-

-SRT通信の実験

-受信側

-gst-launch-1.0 srtsrc uri="srt://0.0.0.0:38089?mode=listener" keep-listening=true ! tsdemux ! h264parse ! avdec_h264 ! videoconvert ! glimagesink sync=false

-送信側

-gst-launch-1.0 rtspsrc location=rtsp://cam:Cam12345@192.168.0.10/Src/MediaInput/stream_1 latency=0 ! rtph264depay ! avdec_h264 ! videoconvert ! videoscale ! video/x-raw,width=640,height=360 ! videorate ! video/x-raw,framerate=5/1 ! x264enc speed-preset=ultrafast tune=zerolatency key-int-max=1 ! mpegtsmux ! srtserversink uri = \"srt://192.168.101.10:38089\" latency=500

2024,江端さんの技術メモ

dockerは、どのOS環境でも動くを唄っていますが、基本的に、わたしは、どんなパッケージであろうとも、「これ」を信じていません。

とくに時系列方向については、全く信用していません。

ともあれ、ノートPCにtomioka_dbをdocker-compose.ymlで再構築した時、以下の部分の変更が必要でしたので、逐次メモしていきます。

#version: '3.9'
services:
  db:
    build:
      context: .
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: tomioka_db
    ports:
      - "15432:5432"
    volumes:
      - ./tomioka_db:/tomioka_db
      - db-data:/var/lib/postgresql/data
  osm2pgsql:
    # image: openfirmware/osm2pgsql:latest
    image: osmtw/osm2pgsql:latest  # イメージ名を変更
    environment:
      PG_PORT_5432_TCP_ADDR: db
      PG_PORT_5432_TCP_PORT: 5432
      PG_ENV_OSM_DB: tomioka_db
      PG_ENV_OSM_USER: postgres
      PG_ENV_POSTGRES_PASSWORD: password
    volumes:
      - ./tomioka_db:/tomioka_db
volumes:
  db-data:

 

2024,江端さんの忘備録

私は今でも、Meadow3を使っています。

I still use Meadow3.

Meadow3とは、Windowsに特化したemacsのことです。

Meadow3 is a Windows-specific emacs.

WindowsNT 4.0より前から使っていますが、今も使い続けています。

I have been using it since before Windows NT 4.0 and continue to use it.

なぜか ―― 動くからです。

Why -- because it works.

現在、Windows11上でも動き続けています。

Currently, it continues to run on Windows 11.

vscodeのemacsキーバインドマッピング 諦めました。

-----

動き続けている限り、使わない理由はありません。

There is no reason not to use it as long as it keeps moving.

.emacsをメンテナンスする気力もありませんので、キーバインドも、当時から固定のままです。

I don't have the energy to maintain .emacs, so key bindings have remained fixed since that time.

もはやMeadow3は、私の体の一部といっても過言ではありません。

It is no exaggeration to say that Meadow3 is now a part of my body.

-----

Meadowが、バージョンアップしたWindowsOSで動かなくなった時に、私の中でも何かが終わるような気がしています。

I feel that something will end for me when Meadow stops working with the upgraded Windows OS.

―― と言いながら、次女のPCにMeadow3をインストールして、今、それで、この文章を書いています。

-- but I installed Meadow3 on my second daughter's PC and am now writing this text with it.

あと、次女のノートPCに大量に貼ってあるステッカーが、ちょっとアバンギャルドで、このPCを学会会場に持ち込む勇気が出ませんでした。

Also, the large number of stickers on my second daughter's laptop was a bit avant-garde, and I could not find the courage to bring this computer to the conference venue.

という訳で、こんなの購入して、ノートPCに貼りつけていました。

So I bought one like this and stuck it on my laptop.

返却時に、元に戻して返すつもりですが。

I intend to return it to its original state when I return it.

2024,江端さんの技術メモ

エクスプローラで、ファイルをコピーする場合、同じファイル名の場合には時刻が新しい場合のみ上書きしたいですがどうすれば良いですか
ChatGPT
ChatGPT
Windowsエクスプローラでファイルをコピーする際、同じファイル名の場合は時刻が新しい場合のみ上書きするという機能は標準では提供されていません。しかし、以下の方法でこの操作を実現できます。

方法1: コマンドプロンプトでrobocopyを使用
Windowsにはrobocopyという強力なコマンドラインツールがあり、これを使用してファイルのコピーを行うと、指定した条件に基づいてファイルを上書きできます。

以下の手順で行います。

コマンドプロンプトを管理者権限で開く

以下のrobocopyコマンドを実行

cmd
コードをコピーする
robocopy "コピー元フォルダのパス" "コピー先フォルダのパス" /XO
ここで、/XOオプションは古いファイルを除外します。これにより、コピー元フォルダのファイルがコピー先フォルダのファイルより新しい場合にのみ上書きされます。


コピー元フォルダがC:\source、コピー先フォルダがD:\destinationの場合、次のように入力します。

cmd
コードをコピーする
robocopy "C:\source" "D:\destination" /XO


cmd.exeを管理者モードで立ち上げ

C:\WINDOWS\system32>robocopy "f:\しゅらばしゅう" "\\192.168.0.23\ynu-share\しゅらばしゅう_フルバックアップ" /XO /E /Z

C:\WINDOWS\system32>robocopy "\\192.168.0.10\usb_mount" "\\192.168.0.23\ynu-share\usb_mount_フルバックアップ" /XO /E /Z

C:\WINDOWS\system32>robocopy "g:home\ebata\tomioka3B\src" "\\192.168.0.9\share\tomioka3B\src" /XO /E /Z
C:\WINDOWS\system32>robocopy "g:home\ebata\hakata" "\\192.168.0.9\share\hakata" /XO /E /Z

======

robocopy "f:\しゅらばしゅう" "\\192.168.0.23\ynu-share\しゅらばしゅう_フルバックアップ" /XO /E /Z

 

robocopy "\\192.168.0.10\usb_mount" "\\192.168.0.23\ynu-share\usb_mount_フルバックアップ" /XO /E /Z

 

robocopy "g:home\ebata\tomioka3B\src" "\\192.168.0.9\share\tomioka3B\src" /XO /E /Z

 

robocopy "g:home\ebata\hakata" "\\192.168.0.9\share\hakata" /XO /E /Z

 

echo

======

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー
-------------------------------------------------------------------------------
  開始: 2024年6月23日 10:23:39
   コピー元 : G:\home\ebata\tomioka3B\src\
     コピー先 : \\192.168.0.9\share\tomioka3B\src\
    ファイル: *.*
  オプション: *.* /S /E /DCOPY:DA /COPY:DAT /Z /XO /R:1000000 /W:30
------------------------------------------------------------------------------
                           4    G:\home\ebata\tomioka3B\src\
                           2    G:\home\ebata\tomioka3B\src\.vscode\
                          20    G:\home\ebata\tomioka3B\src\Agent\
                           4    G:\home\ebata\tomioka3B\src\Agent\ldarp\
                           2    G:\home\ebata\tomioka3B\src\Agent\old\
                          14    G:\home\ebata\tomioka3B\src\Agent - kese09161446\
                           2    G:\home\ebata\tomioka3B\src\Agent - kese09161446\ldarp\
                           2    G:\home\ebata\tomioka3B\src\Agent - kese09161446\old\
                          14    G:\home\ebata\tomioka3B\src\Agent-kese-09161400\
                           2    G:\home\ebata\tomioka3B\src\Agent-kese-09161400\ldarp\
                           2    G:\home\ebata\tomioka3B\src\Agent-kese-09161400\old\
                           1    G:\home\ebata\tomioka3B\src\agent_db\
                          14    G:\home\ebata\tomioka3B\src\CartはAgentに併合\
                           1    G:\home\ebata\tomioka3B\src\CartはAgentに併合\ldarp\
                           2    G:\home\ebata\tomioka3B\src\CartはAgentに併合\old\
                           1    G:\home\ebata\tomioka3B\src\inc\
                           5    G:\home\ebata\tomioka3B\src\Join\
                           1    G:\home\ebata\tomioka3B\src\Join\ldarp\
                           3    G:\home\ebata\tomioka3B\src\ldarp\
                           4    G:\home\ebata\tomioka3B\src\old\
                          22    G:\home\ebata\tomioka3B\src\old\doc\
                         253    G:\home\ebata\tomioka3B\src\others\
                           1    G:\home\ebata\tomioka3B\src\others\.vscode\
                           8    G:\home\ebata\tomioka3B\src\others\chart\
                         105    G:\home\ebata\tomioka3B\src\others\csvファイルのバックアップ\
                           1    G:\home\ebata\tomioka3B\src\others\main49\
                           1    G:\home\ebata\tomioka3B\src\others\main50\
                           8    G:\home\ebata\tomioka3B\src\PrumeMobile\
                          10    G:\home\ebata\tomioka3B\src\PrumeMobile\chart\
                           9    G:\home\ebata\tomioka3B\src\PrumeMobile\chart2\
                           8    G:\home\ebata\tomioka3B\src\PrumeMobile\old\
                          12    G:\home\ebata\tomioka3B\src\PrumeMobile\static\
                          25    G:\home\ebata\tomioka3B\src\trip_cluster\
100%      新しいファイル                     105        #robocopy#
100%            新しい              7540        main.go
                          12    G:\home\ebata\tomioka3B\src\trip_cluster\bic\
100%      新しいファイル                     858        plot_cluster7.gnuplot
                           4    G:\home\ebata\tomioka3B\src\trip_cluster\bus\
100%      新しいファイル                     357        plot_cluster2.gnuplot
100%      新しいファイル                     858        plot_cluster2.gnuplot~
                          56    G:\home\ebata\tomioka3B\src\trip_cluster\data(最初に手動で作成)\
                           9    G:\home\ebata\tomioka3B\src\trip_cluster\walk\
100%      新しいファイル                     775        plot_cluster7.gnuplot
100%      新しいファイル                     858        plot_cluster7.gnuplot~
                        2001    G:\home\ebata\tomioka3B\src\trip_normalization\
100%            新しい              4466        main.go
100%      新しいファイル                    3678        main.go~
                          73    G:\home\ebata\tomioka3B\src\trip_test\
                          75    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018\
100%            新しい             23276        main.go
100%      新しいファイル                     124        robocopy
                           0    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018\main copy.go(5\
                          75    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018_harugakkai\
                           6    G:\home\ebata\tomioka3B\src\trip_test_tomioka2018_harugakkai\others\
                           4    G:\home\ebata\tomioka3B\src\trip_tomioka2018\
                           4    G:\home\ebata\tomioka3B\src\trip_tomioka2018\others\
100%      新しいファイル                     587        dummy.txt
100%      新しいファイル                      58        dummy.txt~
100%            新しい              3272        main.go
        新しいディレクトリ       4      G:\home\ebata\tomioka3B\src\trip_tomioka2018_harugakkai\
100%      新しいファイル                  162161        agent_od_test.csv
100%      新しいファイル                    9022        libdarp.go
100%      新しいファイル                   15470        main.go
100%      新しいファイル                   18255        tools.go
        新しいディレクトリ       4      G:\home\ebata\tomioka3B\src\trip_tomioka2018_harugakkai\others\
100%      新しいファイル                  162161        agent_od_test.csv
100%      新しいファイル                     587        dummy.txt
100%      新しいファイル                      58        dummy.txt~
100%      新しいファイル                    3272        main.go
------------------------------------------------------------------------------
                  合計     コピー済み      スキップ       不一致        失敗    Extras
   ディレクトリ:        47         2        45         0         0         0
     ファイル:      2890        22      2868         0         0         0
      バイト:   35.39 m   408.0 k   34.99 m         0         0         0
       時刻:   0:00:02   0:00:01                       0:00:00   0:00:01
       速度:              278161 バイト/秒
       速度:              15.916 MB/分
   終了: 2024年6月23日 10:23:42