rts-sim-module/repository/physical_section.go

203 lines
4.6 KiB
Go
Raw Normal View History

package repository
import (
"fmt"
2023-12-05 15:01:34 +08:00
"joylink.club/rtsssimulation/repository/model/proto"
"joylink.club/rtsssimulation/util/number"
)
// 物理区段
type PhysicalSection struct {
Identity
len int32 //长度 mm
checkPoints []*CheckPoint //将此区段分隔出来的所有(非区段边界)检测点
// A/B端关联的设备端口非道岔物理区段/道岔)
aRelation DevicePort
bRelation DevicePort
// 非道岔物理区段A/B端的公里标
aKm *proto.Kilometer
bKm *proto.Kilometer
turnouts []*Turnout //道岔物理区段关联的道岔
// 关联的设备(目前有信号机、应答器、(非区段边界)检测点)
devices []Identity
//aKm/bKm对应的LinkPosition
aLinkPosition *LinkPosition
bLinkPosition *LinkPosition
//在Link上的区间start小于end
2023-11-10 11:05:07 +08:00
linkRanges []*LinkRange
2023-10-31 11:30:17 +08:00
//物理区段所属集中站
2023-10-31 15:55:16 +08:00
centralizedStation string
}
func NewPhysicalSection(id string) *PhysicalSection {
return &PhysicalSection{
Identity: identity{id, proto.DeviceType_DeviceType_PhysicalSection},
}
}
func (p *PhysicalSection) bindLinkRange(link *Link, one int64, two int64) {
p.linkRanges = append(p.linkRanges, &LinkRange{
link: link,
start: number.Min(one, two),
end: number.Max(one, two),
})
}
func (s *PhysicalSection) PortNum() int {
return 2
}
func (s *PhysicalSection) ALinkPosition() *LinkPosition {
return s.aLinkPosition
}
func (s *PhysicalSection) BLinkPosition() *LinkPosition {
return s.bLinkPosition
}
func (s *PhysicalSection) ARelation() DevicePort {
return s.aRelation
}
func (s *PhysicalSection) BRelation() DevicePort {
return s.bRelation
}
2023-09-22 16:42:19 +08:00
func (s *PhysicalSection) AKilometer() *proto.Kilometer {
return s.aKm
}
func (s *PhysicalSection) BKilometer() *proto.Kilometer {
return s.bKm
}
2023-10-23 17:39:39 +08:00
// IsAxleSection 判断是否为计轴区段
func (s *PhysicalSection) IsAxleSection() (bool, error) {
if len(s.checkPoints) > 0 {
axleCount := 0
for _, cp := range s.checkPoints {
if cp.pointType == proto.CheckPointType_AxleCounter {
axleCount++
}
}
if axleCount == len(s.checkPoints) {
return true, nil
} else if axleCount == 0 {
return false, nil
} else { //axleCount>0&&axleCount<len(s.checkPoints)
return false, fmt.Errorf("物理区段中检测点不纯")
}
} else {
return false, fmt.Errorf("物理区段没有检测点")
}
}
2023-10-31 15:55:16 +08:00
func (s *PhysicalSection) CentralizedStation() string {
return s.centralizedStation
}
func (s *PhysicalSection) bindDevicePort(port proto.Port, devicePort DevicePort) error {
_, isSectionPort := devicePort.(*PhysicalSectionPort)
_, isTurnoutPort := devicePort.(*TurnoutPort)
if !isSectionPort && !isTurnoutPort {
2023-12-05 15:01:34 +08:00
return fmt.Errorf("物理区段不能与[%s]类型的设备端口关联", devicePort.Device().Type())
}
switch port {
case proto.Port_A:
s.aRelation = devicePort
case proto.Port_B:
s.bRelation = devicePort
default:
2023-12-05 15:01:34 +08:00
return fmt.Errorf("物理区段无端口[%s]", port)
}
return nil
}
// 绑定区段边界公里标。(仅限非道岔物理区段调用)
func (s *PhysicalSection) bindBoundaryKm(km *proto.Kilometer, port proto.Port) error {
if km == nil || (km.CoordinateSystem == "" && km.Value == 0) {
2023-12-05 15:01:34 +08:00
return nil
}
switch port {
case proto.Port_A:
s.aKm = km
case proto.Port_B:
s.bKm = km
default:
2023-12-05 15:01:34 +08:00
return fmt.Errorf("区段无端口[%s]", port)
}
return nil
}
// 道岔物理区段绑定道岔
func (s *PhysicalSection) bindTurnouts(turnouts ...*Turnout) {
for _, turnout := range turnouts {
s.turnouts = append(s.turnouts, turnout)
for _, cp := range turnout.checkPoints() {
s.bindDevices(cp)
}
}
}
func (s *PhysicalSection) bindDevices(devices ...Identity) {
for _, device := range devices {
s.devices = append(s.devices, device)
cp, ok := device.(*CheckPoint)
if ok {
s.checkPoints = append(s.checkPoints, cp)
}
}
}
func (s *PhysicalSection) findOtherDevicePort(port proto.Port) DevicePort {
switch port {
case proto.Port_A:
return s.bRelation
case proto.Port_B:
return s.aRelation
}
return nil
}
func (s *PhysicalSection) findOtherBoundaryKmByPort(port proto.Port) *proto.Kilometer {
switch port {
case proto.Port_A:
return s.bKm
case proto.Port_B:
return s.aKm
}
return nil
}
func (s *PhysicalSection) findBoundaryKmByPort(port proto.Port) *proto.Kilometer {
switch port {
case proto.Port_A:
return s.aKm
case proto.Port_B:
return s.bKm
}
return nil
}
2023-11-10 16:03:33 +08:00
func (s *PhysicalSection) LinkRanges() []*LinkRange {
return s.linkRanges
}
type PhysicalSectionPort struct {
section *PhysicalSection
port proto.Port
}
func (p *PhysicalSectionPort) Port() proto.Port {
return p.port
}
func (p *PhysicalSectionPort) Device() PortedDevice {
return p.section
}